Personal wechat public number: Practice, welcome to pay attention to communication!
When App project complex a certain degree, the project component is essential to componentization can better classify the features, mentioned componentization someone might think of modular, actually componentization and modularization is the essence of the same, is to code reuse business decoupling, modular mainly in accordance with the business divisions, and componentization mainly according to the functional division, Open the door of componentization from the most basic aspects of componentization.
- A jump between components
- Dynamically create
- Resource conflict
- Static constants
A jump between components
In componentization, the two function modules do not depend on each other directly, but depend on each other indirectly through the Base Module. When the activities between components jump to the interface, they often cannot reference the activities in the other module because there is no interdependent relationship.
Implicit jump
An implicit jump is implemented using Android’s native Intent matching mechanism, that is, using an Action to jump to the corresponding Activity. In this way, an implicit jump can be implemented between activities across modules. Note that: If you move an Activity out of its module without moving the corresponding jump, an exception will occur if the jump continues. If you use an implicit Intent jump, verify that the Intent will be received. You need to call the resolveActivity() method on the Intent to determine that at least one application can handle the Intent. You can also set false to exported to ensure that only your own App can start the corresponding component by implicitly jumping to the Intent.
ARouter jump
In Android development, modules can be regarded as different networks, and the corresponding Router is the transfer station connecting each module. This transfer station can handle the parameters of page jump in a unified manner. ARouter is a page jump route from Ali open source. ARouter can be used instead of implicit jump to complete the jump between different modules, different components and the process of listening, parameter transfer, etc. ARouter supports path jump and URL jump two ways, the use of ARouter is very flexible, the specific use of this is not introduced here. Its use will be explained in detail in a separate article, but the comparison between ARouter and traditional Android jumps is as follows:
- A display jump depends on a class, while a route jump jumps through a specified path.
- Implicit jumps are centrally managed through AndroidManifest, making collaborative development difficult;
- Native uses AndroidManifest for registration, while routes use annotations for registration
- After the original startActivity, the jump process is controlled by the Android system, and the route jump uses AOP aspect programming to intercept and filter the jump process.
Dynamically create
One of the most important aspects of component-based development is to decouple modules and components as much as possible. This makes it easy to think of Java’s reflection mechanism, which uses reflection to get all the information about a class at runtime, and then dynamically manipulate the properties and methods of that class. If the Fragment is used as a component alone, and the Fragment does not need to be removed, if it is a regular Fragment, the App will crash because the Fragment cannot be indexed. If you use reflection to create a Fragment, at least the App will not crash. You can catch exceptions to complete the logic, which reduces the coupling. As you can see, while reflection has some performance issues, using reflection does reduce coupling to some extent, and learning the componentized Java reflection mechanism should be a necessary part of it.
Componentized development requires that each component run independently. In general, each component has a certain initialization step. The best case is that the project requires the same initialization for several components, which can be done in the BaseModule. In general, each component is initialized differently. You might want to initialize each component in its own Application. If you initialize each component in its own Application, it will inevitably cause some problems in the final compilation due to the merging of the applications. Reflection is also thought of here. Initialization files are created in each component, and then initialization operations of each component are completed through reflection in the final Application. Here, dynamic configuration of Application in componentized development is completed through Java reflection mechanism.
Resource conflict
If the Android: Name attribute is specified in ModuleA’s AmdroidManifest file during componentized development, The AndroidManifest file of the main App Module also uses the Android: Name attribute to specify the corresponding Application. To resolve the conflict, use tools:replace=” Android :name” in the AndroidManifest file of the main App Module. Use the replace attribute to indicate that this attribute, the Android: Name attribute under the tag, can be replaced during compilation, The Application specified according to the AndroidManifest file replacement rules should be the Application specified in the App Module.
For example, I used SMSSDK in one function Module of the project to complete the function of SMS verification. Since it was not used elsewhere, I only introduced it into the function Module to be used. If other modules use SMSSDK, you should import SMSSDK into BaseModule. MobSDK will specify com.mobs.MobApplication as the Application of this Module. At this time, the android:name attribute of the AndroidManifest file will conflict when the overall compilation and packaging. The solution, of course, is to use the Replace property. AndroidManifest file merge after the main conflict is this problem, of course, other attributes under the conflict, also use the replace attribute. In the actual development of more verification will be more rewarding.
Modular development in addition to note is to prevent resource name as leading to the merger, because the conflict caused the resource reference errors or some resource loss, such as string and color resources while waiting for the merger will be replaced by loading of the resources of the same name, behind the idea is to solve the on the resource name should have certain rules, You can force the developer to ensure that the resource name is unique by setting the “resourcePrefix “component name in the build.gradle file. It is recommended that the resource name format in the Module be “Module name-function-Other”.
Static constants
In componentized development, each component is finally merged as a Lib Module. Static variables defined in the R.Java file in the Lib Module are not declared final, which means that the corresponding constants cannot be used in the component Module. In this case, the switch statement cannot be used, which requires an if statement to be used in the component instead of the switch statement. Of course, this is not a problem when the component is running independently.
Butterknife is often used in development. It is very convenient to annotate views and View events. It adopts compile-time annotation mechanism, and only constants can be used in annotations. Therefore, IN componentized development of Butterknife, R2 should be used instead of R. R2 is actually a copy of R, and the declared variable of R2 is final. Therefore, if Butterknife is used in componentized development, R2 should be used instead of R in the corresponding annotations.