Android ASM implements Application componentization

1. Introduction

Many Android projects use componentization. But componentized projects, where each component wants to use the main project’s application, are cumbersome and not well decoupled.

2. Solution comparison

Then I saw a lot of articles dealing with decoupling in the form of reflection or annotations APT.

Mode of reflection

It will affect startup performance, so it is definitely not recommended to use this scheme when optimizing app startup

Apt annotations

It’s a hassle to annotate every model

ASM way

No reflection, no notes. The compiler automatically registers instances in the Model into the app. Convenient and quick

3. Source code address

GitHub

4. Usage

Add the dependent

  • Add dependencies to build.gradle in the project root directory:
repositories {
  mavenCentral()
}
dependencies {
    classpath 'the IO. Making. Cnoke. Startup: register: 1.1.2'
}
Copy the code
  • Add it in the main project (usually app) build.gradle
plugins {
    id 'com.android.application'
    id 'startup-register'// Add this plug-in
}
Copy the code
  • Add dependencies to the build.gradle project you are using:
dependencies {
    implementation "IO. Making. Cnoke. Startup: API: 1.1.2." "
    // Or the base module build.gradle is introduced with an API so that all modules can use it
    / / API "IO. Making. Cnoke. Startup: API: 1.1.2." "
}
Copy the code

Begin to use

  1. Project application inherits com. Cnoke. Startup. Application. StartUpApplication
class MyApplication : StartUpApplication() {}Copy the code
  1. Wrote a class implements the com Module. Cnoke. Startup. Application. The IApplication interface (the class must be used temporarily kotlin implementation)
open class Test1 private constructor(): IApplication{

    /** * this method must be used to implement singletons. Otherwise the project will report an error */
    companion object {
        val instance: Test1 by lazy {
            Test1()
        }
        const val TAG = "test1"
    }

    override fun attachBaseContext(context: Context) {
        Log.e(TAG,"attachBaseContext")}override fun onCreate(a) {
        Log.e(TAG,"onCreate")}override fun onTerminate(a) {
        Log.e(TAG,"onTerminate")}override fun onLowMemory(a) {
        Log.e(TAG,"onLowMemory")}override fun onTrimMemory(level: Int) {
        Log.e(TAG,"onTrimMemory")}override fun onConfigurationChanged(newConfig: Configuration) {
        Log.e(TAG,"onConfigurationChanged")}}Copy the code

Completing Test1 in the Module above will follow the application lifecycle of the project

Application does not want to inherit StartUpApplication

Instantiate FinalAppRegister in Application and call the corresponding method of FinalAppRegister in each lifecycle. See how StartUpApplication is implemented

open class StartUpApplication : Application() {

    private val appRegister by lazy { FinalAppRegister() }

    override fun attachBaseContext(base: Context) {
        super.attachBaseContext(base)
        appRegister.attachBaseContext(base)
    }

    override fun onCreate(a) {
        super.onCreate()
        appRegister.onCreate()
    }

    override fun onTerminate(a) {
        super.onTerminate()
        appRegister.onTerminate()
    }

    override fun onConfigurationChanged(newConfig: Configuration) {
        super.onConfigurationChanged(newConfig)
        appRegister.onConfigurationChanged(newConfig)
    }

    override fun onLowMemory(a) {
        super.onLowMemory()
        appRegister.onLowMemory()
    }

    override fun onTrimMemory(level: Int) {
        super.onTrimMemory(level)
        appRegister.onTrimMemory(level)
    }

    fun initDefaultTask(a){
        appRegister.defaultTask()
    }
}
Copy the code

You can see that classes in Test1 and Test2 are called when application starts

5. Use ASM to add a coroutine asynchronous initialization scheme

Android Kotlin Coroutine implementation Application asynchronous startup framework – Juejin (cn)