Zhang Mingqing, the Android technical expert of APP, has published two articles on the componentization of Android, and opened the componentization project, which has received a good response. To this end, xiaobian specially interviewed Zhang Mingqing teacher himself, to understand the story behind its componentization. This article is a compilation of the interviews.
What is componentization?
 
Modularization, plug-in, and componentization

In technical development, modularity refers to breaking up code, using modularity to divide and conquer and decouple layers of code when our code is particularly bloated. Specific to the Android field, the specific implementation method of modularization is divided into plug-in and component.

 
The difference between plug-in and componentization

A complete set of plug-ins or components must be able to achieve single debugging, integrated compilation, data transfer, UI jump, life cycle and code boundaries. The most important and only difference between plug-in and componentization is that plug-in can dynamically add and modify modules on the line, while componentization has relatively weak dynamic ability. It can only dynamically load and unload existing modules on the line, but cannot add or modify them.

 
How to choose between plug-in and componentization?

An important principle in deciding between pluginization and componentization is: Does APP have the need to dynamically add or modify online modules? If such dynamic demand is weak, plug-in is not needed. Generally speaking, e-commerce or advertising products have a strong need for this, while knowledge service products like “Get APP” are refined for each function. This kind of instant dynamics is not required, so plug-in is not required.

If your product is highly dynamic, you need to weigh both aspects before choosing plug-in. First, pluginization inevitably unhooks some system apis, which inevitably leads to compatibility problems, so each plug-in solution needs a special team to be responsible for maintenance; Second, the time needed to dismantle plug-ins from a project with complex business logic may be very large, and the impact on the development pace needs to be considered.

Therefore, componentalization is a good or even the best option for most products, it has no compatibility, can be easily broken down, and has few technical obstacles to be implemented more smoothly. Especially for products that need to be split, componentization is a fallback solution that can be executed more quickly and will be a necessary step in the future if the migration to plug-in is made.

 
What is “thorough” componentization

I call this project is completely modular, mainly in order to emphasize two points: one is the boundary between components code, directly between components direct reference (compile) is to avoid, once done, will inevitably lead to direct the use of other components of the concrete implementation class, so for interface programming requirements become meaningless. Even more seriously, the decision to load or unload components dynamically can cause serious crashes. So only when code isolation is achieved can the componentization solution be described as “thorough”.

In the current scenario, components are completely invisible to each other during coding, thus eliminating the need to use specific implementation classes directly, but automatically packaging dependent components when compiling and packaging. This scheme is a complete scheme with six functions, covering all the cases that need to be considered in componentization.

Given the “complete” componentization, how can the main project indirectly reference individual components once the code is decoupled? The solution uses a configuration file, and each component declares other components it needs. The configuration is divided into debug and release, which can be switched more flexibly between daily development and formal packaging.

The solution uses a custom Gradle plug-in that reads the configuration files of each component and builds dependencies between components. This plugin analyzes the running task and determines if it is a package. If it is (such as assembleRelease), it automatically introduces it based on the configuration. If it is not (such as sync /build), it does not. That is, components are completely invisible to each other during code writing, thus eliminating the use of concrete implementation classes directly.

However, when compiling and packaging, dependent components are automatically packaged. Of course, it also involves how to transmit data between components in the way of “interface + implementation”, and how to load each component. There are mature solutions in the scheme.

Another nice feature of the gradle plugin is that it can automatically identify and modify the properties of components. It can identify which component is currently being debuggable, and then change this component to an Application project and other components to a Library project. So whether you want to compile a component separately or integrate it into other components for debugging, there is no need to do any manual modification, it is quite easy to use.

Why “complete componentization”?

At the beginning of the “Get APP” Android side of the code component split, “Get APP” has been a product of tens of millions of users. After all that time, hundreds of thousands of lines of code piled up and took about 10 minutes to compile, which seriously affected development efficiency.

Because the business is complex and the code is intertwined, everyone has a serious code burden when writing new requirements. They spend more time getting familiar with the previous code than the development time of the new requirements. And each change required extensive regression by the tester, so the productivity of the entire development team was affected. In this case, the implementation of componentization is imminent.

How to Achieve “Complete Componentization”

Because of the domestic plug-in research is relatively hot, and the research enthusiasm for componentization is relatively weak. When designing the componentization scheme of “get APP”, I looked up almost all the componentization articles, but could not find a complete scheme supporting the six functions mentioned above, so I had to start from scratch. The “Complete Componentization” solution can jump to read the Android Complete Componentization solution practice and the Android Complete Componentization demo link:

http://www.jianshu.com/p/59822a7b2fad

Problems to be paid attention to in the process of componentization

It is a difficult process to apply the scheme from paper to practice, during which we should pay attention to two aspects: one is the continuous improvement of technical details, and the other is the consensus building of the team.

The technical problem is how to make the solution more flexible, requirements are always more complex than expected, and the previous design may not be able to meet special requirements, or it may have to break the previously determined split principles. This is when you need to go back and look at the whole plan and see if you can make some changes. Scheme and data transmission in the UI to jump two functions are separate, which is in the actual split to make a choice, because the data transmission more frequent, more diverse and interactive form, using a standardized routing protocol is difficult to meet, so the data transmission changed to the form of interface + for interface programming can be more flexible to handle these situations.

In addition to technical issues, more important is the team’s consensus. Implementing a componentized split requires everyone on the team to agree on a common direction, both in terms of solutions and technical implementation details.

To this end, do several more group sharing discussions before the split, from the formulation of the plan to every implementation, involve most of the team members. It is called sharpening the knife without miscutting wood. On this premise, the team’s consensus building will have great value to the improvement of work efficiency in the later period. Established consensus, but also need to establish unified rules, although all roads lead to Rome, but in a product, still need to choose a unified road, otherwise even if split, the effect will be greatly compromised.

What’s the difference between iOS and Android componentization?

No matter Android or iOS, the problems to be solved are the same, so the functions to be realized in the componentization scheme (namely, the above six functions) are the same, so the componentization of the two are basically the same.

There is a slight difference in the way of technology implementation. Because the development technology used by the two platforms is different, the componentization of Android may need to consider the migration to plug-in. Once there is a strong demand for dynamic changes in the later period, it can be quickly switched over. Currently, Apple officially doesn’t allow that kind of dynamism, so it’s a little less of a consideration. However, iOS can also dynamically load and unload components, so it is necessary to pay special attention to issues such as life cycle, code boundaries and so on. However, some iOS componentalization schemes may consider relatively little in this respect.

Specific results after componentization

Modular code structure clear, hierarchical structure and the interaction between the very clear, any one of the team can easily create the code structure diagrams, this is not going to do it before, and each component of compile time from 10 minutes to a few seconds, has made great improve the work efficiency, the key still after decoupling, Each time you develop requirements, you are faced with less and less code, and you don’t have to carry so much code burden, which can be said to achieve the ideal situation of “less code to write”.

In fact, componentization of external output is also very considerable, now that a version of the development is completed, we can tell the test that this issue will return to the “listen to the book every day” component, the other need not return. This kind of confidence is absolutely not before, the test pressure can also be much less. More importantly, our components can be reused. “Deweapp” will launch new products, and they can directly use existing components, saving a lot of work of remanufacturing wheels, which is also helpful for the improvement of the efficiency of the whole company.

Xiaobian recommendation:

Want to know how the first Mac was developed? Want to learn more about Apple’s engineering culture? Want to learn how silicon Valley people make products the best they can? Want a taste of Steve Jobs’ leadership? This book can tell you all about it. Click [read the original text] to buy, there are exquisite bookmarks for free oh ~