Recently, Google officially launched the AS3.0 version, and the plugin for Gradle has been upgraded to 3.0.0. At present, various open source libraries are doing the compatibility of Gradle3.0.0. I have also upgraded the open source component solution AndroidComponent. DDComponent is compatible with gradle3.0 and can be used directly. For information on how to migrate to gradle3.0.0, see the official migration guide.
While there were no compatibility issues, there was an unexpected benefit during the upgrade process, which was that gradle3.0.0 has better and better support for code isolation. Why the focus on “code isolation”? You can review the previous two articles on the practice of Android radical componentization and the release of Android Radical Componentization demo. The DDComponent componentization scheme mentioned in these two articles is labeled as “radical”. Although it is a bit of an exaggeration, But mainly to emphasize the difference between DDComponent and previous componentalization solutions is that DDComponent implements absolute isolation between components, completely invisible from each other during code development, a completely decouple idea. To achieve this isolation, I make an artificial distinction between compile and run time, with no dependencies between components at compile time (during development), but surface-add dependencies at package time and run time. See the previous two articles and the Github source code for details.
Gradle does have a similar feature. Apk dependency syntax ensures that dependent libraries are only visible at runtime, but not at compile time. This should have worked for me, but I ran into a pit: in gradle2.+, apK dependencies can only be JARS, not AAR, but the output of our component is aar because it contains various resources! So I finally chose to give up apK syntax.
In the latest Gradle3.0.0, apk has been replaced with runtimeOnly, which does the same thing, but I noticed that runtimeOnly can add AAR dependencies! I’m really excited about this. Isn’t this the feature I’ve been dreaming about? With this sword, the componentized scheme can be made thinner ah. So I experimented on the App and came to the conclusion that runtimeOnly does solve some problems, but it is not enough. I’ll elaborate on code isolation, resource isolation, and debug switching (standalone and integrated), as well as what DDComponent can do.
Code isolation
Before we talk about code isolation, let’s take a quick look at gradle3.0.0 syntax changes for adding dependencies.
First of all, compile has been abandoned, but divided into two parts: implementation and API. The API function is basically the same as that of compile before. Implementation is more advanced in that dependencies added with implementation are not referenced by other components at compile time, but are fully visible at run time. This is also a form of code isolation. So for example,
Implementation lib1 implementation lib1 implementation lib1Copy the code
Before gradle3.0.0, it was completely possible for B to reference classes in lib1, but now B can’t do this at compile time, only at run time. This kind of thinking is similar to the idea that “your subordinates’ subordinates are not your subordinates.” But this isolation does not work between components, and in the example above all classes of A are still fully visible to B, that is, no isolation is done. Implementation is an effective way to reduce compile time. As in the example above, lib1 has changed and now you only need to compile A. Before, B might also use lib1, so you need to compile B and A at the same time. According to official advice, you should use Implementation to add dependencies in most cases.
There are also two changes, the APK syntax will be replaced by runtimeOnly and provided will be replaced by compileOnly. One big change to runtimeOnly is aar support, but compileOnly will still only support JARS!
To summarize, gradle3.0.0 has four syntax features and code isolation:
As you can see from the figure above, runtimeOnly has the best code isolation effect! But can it be used directly? The answer is no.
Second, resource isolation
In previous articles, code isolation has been emphasized, but another layer of complete isolation between components is resource isolation, otherwise it is easy to create coupling between components. This is mentioned in the “debug alone” section of this article, where each component needs to specify a resourcePrefix, resourcePrefix, to avoid resource name conflicts after integration. In other words, a complete componentization should not only make code unreferable, but also resources unreferable!
But runtimeOnly is still resource isolated. I tested it on the DDComponent open source library. The app references shareComponent components through runtimeOnly, although the shareComponent code is not visible. But resources can still be used directly by the app and run successfully.
At this point, replacing runtimeOnly with runtimeOnly won’t work. To achieve this effect, you still need to add an artificial layer of control, just like DDComponent, so it doesn’t look thinner from a componentization perspective, but fortunately DDComponent is simple. People who have a certain gradle foundation can easily understand it.
Three, debugging switch
In addition to the resource isolation mentioned above that prevents runtimeOnly from being used directly, there is another usage issue that needs to be addressed, which is also provided by the Compbuild plug-in in DDComponent: automatic switching between separate debugging and integrated debugging. In standalone debugging, the component is an Application project whose output is an APK file, while in integration debugging, the dependent component is a Library project whose output is an AAR file. For runtimeOnly, aar and JAR are supported, but APK is not, so if you want to switch between debug alone and debug integration, you need to manually modify the Runalone configuration and modify the build.gradle configuration file, and then sync it to take effect. This modification is rather cumbersome.
In DDComponent, this problem is solved by “intelligently” identifying the component currently being debugged, setting the component to be debugged as an Application project and silently modifying other components it depends on as a Library project, with immediate effect and complete transparency to the developer. Developers can debug any component by clicking on the RUN section of AS. The figure of the RUN functional area of AS is AS follows:
Four,
To sum up, we can summarize DDComponent and Gradle3.0.0: Gradle3.0.0 provides implementation and runtimeOnly syntax. both of them provide some degree of code isolation. (3) Implementation and runtimeOnly are still available for componentization in terms of resource isolation and debug switches, so use the full isolation and switch functionality provided by DDComponent.
In the source of DDComponent I added the gradle3.0.0 branch, do the corresponding replace rely on grammar, welcome everybody to continue to support “get” app product modular solution, source address: https://github.com/mqzhangw/AndroidComponent