There are a lot of componentized articles on the Internet, but most of them start from the bottom of the details, from the bottom up to give people a sense of this technology “extensive and profound” daunting. The original intention of writing this article is from top to bottom, hoping that others can feel the feeling of “componentization is originally these several things” in the process of reading.

First, let’s look at the differences between componentized projects and traditional projects

In the traditional program

We usually have a core libary module and an APP application module. The logic of business is written in the APP and each function module is placed in different packages. This has the following main disadvantages: 1, the actual business changes very fast, but the coupling degree of a single project business module is too high, affecting the whole body. 2. During the development process, any member can’t focus on their own function points, which affects the development efficiency. 3. Conflicts and code coverage can easily occur in version management. 4. Functional and system tests should be performed every time. 5. No matter how well the subcontracting is done, with the increase of the project, the project will gradually lose the sense of hierarchy, and it will be difficult for others to take over. 6. When we debug a small function, we need to rebuild the whole project every time we modify the code, which is very unreasonable.

In the componentized project

In addition to commonLib and APP components, we divide each business component according to function (we can divide app1, APP2, APP3 and APP4 into four major components). The former package is now the module, which increases the sense of hierarchy. Each functional module can be compiled separately, which speeds up compilation and provides support for unit module testing. Multiplayer developers are responsible for their own modules, directly avoiding versioning conflicts.

Now that we understand the main problem that componentization solves for us let’s see what we need to do, okay

In fact, there are only two problems to be solved in the end:

1. Business components can be compiled either integrally or individually — just by configuring Gradle

2. Page jump and communication between business components — it can be solved by using ARouter of Ali open source

So let’s look at how do we do that

Let’s first look at inter-module dependencies

We can refer to the two components (APP1 and APP2) of ××× for configuration. First of all, the basic structure of our project is as follows:

We need to build a total of 4 components, in addition to 2 functional components, there is a basic core component and a startup app component.

After building the project, we need to configure a separate compiler switch for the two functional components:

There is a problem with the configuration position of the switch. We add it to the gradle.properties file so that every time we change the value we can trigger a rebuild of Gradle, so that we can compile the components separately.

Now that our separate compiled switches are configured, let’s look at the dependencies between components:

For the two functional components, we need to install the separate compilation switch we configured earlier, we need to modify the following two places:

You can see that what we need to change is where I put the red box. When our switch is turned on, we compile it as a separate application and give it a unique applicationId, This allows us to control whether or not it is compiled as an application by itself using the switch we just configured in gradle.properties.

For the app component of the main entrance, we need to do the following configuration:

In addition to configuring the basic core component dependencies, we also need to choose whether to rely on our functional components according to the switch in the Gradle file of app components, which corresponds to the configuration of each functional component.

For other component modules, repeat the above steps to complete the construction of the component framework.

After the componentized framework is built, the page jump and communication between business components need to be solved

First, we borrowed Ali’s ARouter library to facilitate interaction between components, so it is strongly recommended to include ARouter and Core dependencies in every non-core component (including the main Application).

First, how do component pages jump from one another

Before we have been relying on ARouter detailed usage (see https://github.com/alibaba/ARouter), we want to use it to help us achieve a jump to the following steps:

The way to jump is as shown in the figure above, we need to specify the target page, attach the parameters to be sent, and then call navigation() to jump, but some people ask why the target page looks like a path, how is it defined?

  • Start by annotating the page with the @route annotation and defining a path to the page in the path variable
  • For the variables that are being sent in, we’ll just define a field with the same name as the @AutoWired variable, and Arouter will automatically assign to that field
  • Finally, we need to inject the page into ARouter (similar to ButterKnife) and let him do the work we need

This way, we have completed the jump from page to page, is it simpler and more reasonable than our traditional method?

And then how do the components talk to each other

How can app1’s sayHello method be called by other components (including main component and other components)

  • The first step is to create an interface in the core component that exposes the method, define the interface signature, and inherit the Iprovider interface

  • The app1 component then inherits the interface defined in Core and implements the signature method. Here we also use Arouter’s @router annotation to provide routing for this service

  • Finally, we can call this method in other modules using the @Autowired annotation

As you can see, we also use the @AutoWired annotation to initialize the baseService service and inject the page into Arouter to call the methods in the service. The dependency on the service is based on the interface, making it much more flexible!

The basic componentized framework is completed, I hope to see the friends can harvest! If there is wrong place also hope to correct!

Thinking about componentization

  • Dynamic loading and unloading of components. Most business components need to have their own Application, and then perform relevant initialization operations here. In integration mode, only the main component can have Application, so the first question is how to obtain the globally unique Application of the business component. How can a large number of initialization operations of business components be unified into the Application of the main component? If all initialization operations are put into the main Application, then the startup speed and performance cost can be guaranteed.
  • Code isolation. One problem is that we can use Compile Project (‘: XXX ‘) to import components. Although we use interface + implementation architecture, components must be programmed against interfaces, but once we introduce XXX components (especially in the main app), We could have used the implementation classes directly, and our specification for interface programming would have been a dead letter. If any code (intentionally or not) does that, the work we’ve done has been wasted.

Welcome to git Issues

Above project Git (welcome to participate in improvement)

Github.com/YoungBill/A…