1. Model diagram of Android modular design scheme

2. Interface APi-ization of Android modular design scheme

3, Android modular design using proxy mode decoupling

4. SourceSets configuration of Android modular design scheme

5. Launcher of Android modular design scheme

At the beginning of this article, I throw out two questions:

Problem 1: As we all know, with the expansion of the scale of our App, there are more and more business logic and tripartite class libraries to be initialized in the Application, which directly affects the cold startup speed of the App and makes the readability of the code worse. How to properly manage these initialization tasks?

Problem two: in the modular development, there are always some modules to initialize some of the module specific business or class library, how to modify/add this module initialization items, as far as possible do not modify other modules including shell engineering module?

In order to solve these two long-standing problems, Ben has not found a suitable solution after a long time of searching Google. Since there is no ready-made wheel, we can only spend some time polishing a wheel, so based on APT technology, we created this wheel, which is the starter — XStarter

So what is an initiator?

Is a logic of some projects need to initialize the unified management of tool library, it can achieve through simple configuration startup loading sequence and whether the lazy initialization or initialized in the child thread, and itself support modular design, can achieve project decoupling to the greatest extent. So let me briefly describe how XStarter can be used.

Project source code address: github.com/wangkunhui/…

The first step is to introduce project dependencies, starter_version = “1.0.0-rc”.

In a Java module:

android {
  defaultConfig{
    javaCompileOptions {
      annotationProcessorOptions {
         arguments = [STARTER_MODULE_NAME: project.getName()]
      }
    }
  }
}

dependencies {
    implementation "com.wangkh.moduler:XStarter:$starter_version"
    annotationProcessor "com.wangkh.moduler:XStarter-compiler:$starter_version"
}
Copy the code

In the Kotlin module:

apply plugin: 'kotlin-kapt'
kapt {
    arguments {
        arg("STARTER_MODULE_NAME", project.getName())
    }
}

dependencies {
    implementation "com.wangkh.moduler:XStarter:$starter_version"
    kapt "com.wangkh.moduler:XStarter-compiler:$starter_version"
}
Copy the code

Step 2: Register with Application.

XStarter.isDebug = true // Whether it is in test mode
XStarter.emit(DemoApplication.instance) // Start the initiator
Copy the code

The third step is to create the initiator class in the module that needs to initialize data.

@Starter(mainProcessOnly = false)
class KotlinStarter : IStarter {// Class names can be arbitrarily named
    @StarterMethod(priority = 99, isSync = false, isDelay = true)
    public fun initTest(application:Application) { // The method name can be arbitrary
        //TODO executes the logic that needs to be initialized in the module
    }

    @StarterFinish(listen = "initTest")
    public fun listenTest(e:Exception) { // Listen to see if the initTest method is finished. If you do not need to listen, you can not write listenTest method
        Log.e("KotlinStarter"."Test initialization completed")}@StarterMethod(priority = 60, isSync = true, isDelay = true)
    public fun initTest2(a) { // The method name can be arbitrary
	//TODO initializes something else. Since this method does not use Application for initialization, a null argument is ok.}}Copy the code

With this code, the project automatically looks for the KotlinStarter class at startup and calls the life initialization method initTest. If you want to listen for initTest to complete, you can define a listenTest method (method name can be any). However, the string in the listen parameter of the @starterFinish annotation must be the same as the name of the method being listened on.

Notes and parameter description

@starter // Mark the startup management class mainProcessOnly -- Whether it is initialized only in the main process True Only in the main process false All processes are initialized @starterMethod // Mark the startup method, Can only be used in classes that have the @starter modifier. Priority -- The priority of the startup method, [0-99]. A higher value indicates a higher priority. The default value is 50. IsSync -- Whether to initialize synchronously (i.e. in the main thread), true or false No, i.e. in the child thread initialization, default true; IsDelay -- Whether the initialization can be delayed, true or false; The @starterFinish // start method listener can only be used in the @starter modified class. Listen -- specifies the name of the method to listen on;Copy the code

Confuse configuration

-keep public class com.wang.android.starter.executor.**{*; } -keep public class com.wang.android.starter.manager.**{*; }Copy the code

Finally, we will sort out the two questions left at the beginning of the article.

Problem 1: The class libraries that need to be initialized in the Application class are decoupled to each business module, stripping the business code in the Application and providing a unified way to process. With a simple annotation configuration, you can specify the initialization priority of the class library, the initialization thread, and whether the initialization can be deferred, with no additional changes required.

Problem 2: Because the business code in the Application is completely stripped, when we need to modify or add modules to the Module startup class library, we only need to modify the initiator class of the corresponding Module, without changing the code in the shell project.

The idea is to use APT technology to generate the agent class and the management class of the initiator class at compile time, and use the management class to uniformly schedule the methods in all initiators.

Ok, about the launcher part of the introduction is over, if the article can help you, welcome to like comments and attention, exchange discussion ~