JetPack<第八篇>:Start up
【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)
}
手动初始化又叫做延迟初始化。
[本章完...]