前言
官方描述:
The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.
Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.
一、一般的sdk初始化方式
在开发过程中如果需要引用sdk,并且sdk需要初始化的操作,而初始化的方式一般有两种:
1.在Application中直接调用sdk的初始化方法
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
TestSdk1.init(this);
}
}
2.使用ContentProvider初始化:
public class Sdk1InitProvider extends ContentProvider {
@Override
public boolean onCreate() {
TestSdk1.init(getContext());
return true;
}
当然还需要在AndroidManifest中注册这个provider
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lv.jetpack">
<application>
<provider
android:authorities="${applicationId}.init-provider"
android:name=".Sdk1InitProvider"
android:exported="false"/>
</application>
</manifest>
通过上面两种方式进行sdk的初始化,如果数量太多,第一种方式Application中的sdk初始化代码太多,第二种方式如果都放在一个ContentProvider中会导致此ContentProvider代码数量增加。而且每增加一个需要初始化的sdk都要对该ContentProvider文件做改动,不方便合作开发。而如果每个sdk都采用同样的方式将会带来性能问题。
二、App Startup的使用
1.添加引用:
目前的版本号是1.0.0
dependencies {
implementation "androidx.startup:startup-runtime:1.0.0"
}
2.准备
假如现在有两个sdk:TestSdk1和TestSdk2需要初始化
public class TestSdk1 {
private static final String TAG = "TestSdk1";
private static String sId;
private static volatile TestSdk1 sInstance;
public static void init(String id){
sId = id;
Log.e(TAG, "TestSdk1 is initialized");
}
public static TestSdk1 getInstance(){
if (sInstance == null) {
synchronized (TestSdk1.class){
if (sInstance == null) {
sInstance = new TestSdk1();
}
}
}
return sInstance;
}
public void getId(){
Log.e(TAG, sId);
}
}
TestSdk2代码和TestSdk1类似
3.实现Initializer<T>接口
TestSdk1Imp
public class TestSdk1InitImp implements Initializer<TestSdk1> {
@NonNull
@Override
public TestSdk1 create(@NonNull Context context) {
//调用TestSdk1的init()方法完成初始化
TestSdk1.init("id---001");
return TestSdk1.getInstance();
}
@NonNull
@Override
public List<Class<? extends Initializer<?>>> dependencies() {
return Collections.emptyList();
}
}
TestSdk2Imp
如果需要初始化的sdk和其他sdk有依赖关系,参照demo如下
public class TestSdk2InitImp implements Initializer<TestSdk2> {
@NonNull
@Override
public TestSdk2 create(@NonNull Context context) {
//调用TestSdk2的init()方法完成初始化
TestSdk2.init("id---002");
return TestSdk2.getInstance();
}
@NonNull
@Override
public List<Class<? extends Initializer<?>>> dependencies() {
List<Class<? extends Initializer<?>>> dependencies = new ArrayList<>();
//此场景是如果需要初始化的sdk和其他sdk有依赖,并且需要先进行依赖的sdk的初始化
//比如demo中会先执行TestSdk1的初始化,然后执行TestSdk2
dependencies.add(TestSdk1InitImp.class);
return dependencies;
}
}
4.注册Provider和Initializer<T>
添加在AndroidManifest中即可
<provider
android:authorities="${applicationId}.androidx-startup"
android:name="androidx.startup.InitializationProvider"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.lv.jetpack.startup.TestSdk1InitImp"
android:value="@string/androidx_startup"/>
<meta-data
android:name="com.lv.jetpack.startup.TestSdk2InitImp"
android:value="@string/androidx_startup"/>
</provider>
5.运行结果
可以看到不需要在Application中进行初始化操作,也完成了两个sdk的初始化操作
6.实现懒加载
修改AndroidManifest.xml文件中对应的标签<meta-data>,添加tools:node="remove"
<provider
android:authorities="${applicationId}.androidx-startup"
android:name="androidx.startup.InitializationProvider"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.lv.jetpack.startup.TestSdk1InitImp"
android:value="@string/androidx_startup"/>
<meta-data
android:name="com.lv.jetpack.startup.TestSdk2InitImp"
android:value="@string/androidx_startup"
tools:node="remove"/>
</provider>
然后在需要初始化的地方通过调用AppInitializer来实现初始化操作
//TestSdk2Imp初始化
AppInitializer.getInstance(getApplicationContext())
.initializeComponent(TestSdk2InitImp.class);
//调用TestSdk2的getId()方法
TestSdk2.getInstance().getId();
运行结果
可以看到通过配置,实现TestSdk2的懒加载,在需要初始化的位置执行初始化操作即可
7.对性能的影响
通过测试,结和命令
adb shell am start -W -n packagename/packageName.MainActivity
得出的结果是:如果20个左右的sdk通过AppStartUp的方式完成初始化,可以节省大概20ms的时间,数量太少的情况下不明显
三、总结
根据使用方式的猜测和源码的查看,AppStartup其实就是做了通过Provider来完成需要初始化的sdk的初始化操作,而且是多个sdk的初始化操作可以放在一个provider中,方便维护,Application文件因为不需要进行初始化操作,避免了频繁改动,只需要维护一个Provider以及对应的实现类即可,符合单一职责,当然也会产生多个对应的实现类。如果需要初始化的sdk很多,而且是以多个Provider的方式进行初始化的,结合懒加载,可以提高初始化性能
网友评论