JetpackAndroid

JetPack<第八篇>:Start up

2022-11-14  本文已影响0人  NoBugException

【1】依赖

implementation "androidx.startup:startup-runtime:1.0.0-alpha01"

【2】新建初始化类

class SdkInitializer : Initializer<Unit> {
    /**
     * 初始化SDK或者对象的方法
     */
    override fun create(context: Context) {
        Log.e("StartUpDemo", "===SdkInitializer create===");
    }

    /**
     * SdkInitializer初始化使用的依赖
     * 如果没有:直接返回空列表即可
     * 如果有:比如TestInitializer,自动优先初始化TestInitializer之后才会初始化 SdkInitializer
     */
    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        Log.e("StartUpDemo", "===SdkInitializer dependencies===");
        return return mutableListOf(TestInitializer::class.java)
    }
}

SdkInitializer 需要我们自己新建,目的是初始化指定SDK。
Initializer 是start up 依赖中的类,不需要自己定义。
Initializer 是一个接口,定义了 create 和 dependencies 两个方法,dependencies首先被执行。
create 方法中主要目的是初始化SDK,所以,初始化SDK的代码就在该方法中实现。
当想要初始化的SDK有其它依赖时,必须将 指定初始化类 传入 dependencies 方法的集合中。dependencies 返回一个集合,以上代码将 TestInitializer 传入集合中。

class TestInitializer : Initializer<TestInstance> {

    override fun create(context: Context): TestInstance {
        Log.e("StartUpDemo", "===TestInitializer create===");
        return TestInstance.getInstance();
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        Log.e("StartUpDemo", "===TestInitializer dependencies===");
        return Collections.emptyList()
    }
}

Initializer 后面需要跟上泛型,如果是 Unit 类型,则 create 方法没有返回值,如果是 T 类型,,则 create 方法的返回值就是 T。
如果没有依赖的SDK或其它,则 dependencies 方法的返回值是空集合。

以上代码泛型是 TestInstance 类,代码如下:

class TestInstance {

    companion object {
        fun getInstance(): TestInstance {
            return INSTANCE.instance
        }
    }

    private object INSTANCE {
        val instance = TestInstance()
    }
}

【3】注册组件

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        android:multiprocess="true"
        tools:node="merge"><!--确保manifest merger tool能够正确解析冲突的节点, 如果改成 remove ,则禁止自动初始化-->
        <meta-data
            android:name="com.yunchong.jetpack.startup.TestInitializer"
            android:value="androidx.startup" />
        <meta-data
            android:name="com.yunchong.jetpack.startup.SdkInitializer"
            android:value="androidx.startup"/>
    </provider>

注册一个provider,name指定 InitializationProvider 类的全名,InitializationProvider 是start up依赖中的类,不需要自己定义。
authorities 要保证唯一,一般以包名开头(applicationId)。
exported 设置为false,可以保证外部无法访问。
node的常用属性是merge和remove。
merge:确保manifest merger tool能够正确解析冲突的节点。
remove:禁止自动初始化。

meta-data 有两个重要的属性,分别是 name 和 value。
name:指定初始化类的路径;
value:写成 androidx.startup 即可。

【4】如何禁止初始化

注册时,可以使用 node 的取值控制,remove 表示禁止自动初始化。

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        android:multiprocess="true"
        tools:node="remove">
        <meta-data
            android:name="com.yunchong.jetpack.startup.TestInitializer"
            android:value="androidx.startup" />
        <meta-data
            android:name="com.yunchong.jetpack.startup.SdkInitializer"
            android:value="androidx.startup"/>
    </provider>

在provider标签中,设置 tools:node="remove",将禁止TestInitializer和SdkInitializer初始化。
如果想要让局部限制初始化,则可以在meta-data标签中控制。

        <meta-data
            android:name="com.yunchong.jetpack.startup.SdkInitializer"
            android:value="androidx.startup"
            tools:node="remove"/><!--禁止自动初始化-->

【5】自动初始化的执行顺序

注册之后,为了确保自动执行 XXXInitializer 的 dependencies 方法和 create 方法,需要保证node的取值为 "merge"。此时,执行顺序是:

Application:attachBaseContext 
XXXInitializer:dependencies
XXXInitializer:create
Application:onCreate

【6】手动初始化

为了保证手动初始化,首先禁止自动初始化。
将 node 取值为remove,tools:node="remove"

然后,在Activity中或其它地方进行手动初始化:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    // 手动初始化SdkInitializer,当然,在这之前,需要在AndroidManifest中,将SdkInitializer的node值改成remove
    AppInitializer.getInstance(this).initializeComponent(SdkInitializer::class.java)
}

手动初始化又叫做延迟初始化。

[本章完...]

上一篇下一篇

猜你喜欢

热点阅读