Android 中 JetPack(一) Startup的使用

2,071 阅读3分钟

本文知识点

  • Startup的介绍
  • Startup的使用
  • Startup的一些特殊的配置

Startup的简介

在之前我们会在Application中都会有一些初始化的代码(比如一些第三方的库,例如极光推送...),如果比较少的时候还好,但是如果随着项目功能的强大,慢慢的就会造成启动的时间被拖长.但是国内的Android开发者怎么能被这个问题难倒呢?紧接着有人就开始使用ContentProvider进行初始化(其实就是利用ContentProvider初始化拥有上下文进行初始化,具体的实现细节可以百度一下).但是这个解决方案也是有弊端的,如果每个三方库都创建一个ContentProvider进行初始化的话,那么在启动的时候也是一个一个进行初始化了,这样也会造成启动时间被拖慢.所以google在JetPack中就提供了Startup这个组件来让我们优化响应的启动时间(其实就是把ContentProvider统一成一个).

以上就是Startup的由来以及为什么要使用它.

Startup的使用

其实发现我很多时候看别人写文章,然后找不到引用哪个包.^-^

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

1. 创建相应的启动类

class ContextManager private constructor(val context: Context) {//这里可以根据实际需求发生改变

    companion object {
        @Volatile
        private var instance: ContextManager? = null
        fun getInstance(context: Context) =
            instance ?: synchronized(this) {
                instance ?: ContextManager(context).also { instance = it }
            }
    }
}

这里我随便了写了一个单例的类,其实主要目的就是初始化的时候使用上下文,所以可以在Application中初始化.这里只是为了演示,不要在意这些细节...

为了广大读者能顺利的理解,所以这里我就写了一份kotlin又写了一份java的.

kotlin代码

class ContextManagerInitializer : Initializer<ContextManager> {

    override fun create(context: Context): ContextManager {
        return ContextManager.getInstance(context)
    }

    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        return mutableListOf()
    }
}

java代码

public class ContextManagerInitializerJava implements Initializer<ContextManager> {

    @NonNull
    @Override
    public ContextManager create(@NonNull Context context) {
        return ContextManager.Companion.getInstance(context);
    }

    @NonNull
    @Override
    public List<Class<? extends Initializer<?>>> dependencies() {
        return new ArrayList<>();
    }
}

以上两端代码是一样的.然后咱们来分析一下这两个回调.

  • create() 这个方法给你回调一个上下文,这样其实就可以通过上下文进行相应的初始化操作了.返回的就是你泛型传递的类.
  • dependencies() 这个方法的作用就是加入你的初始化依赖与其他的第三方或者组件的话,那么就在这个方法中添加相应的依赖,按照集合的顺序进行相应的处理.

2. 在清单文件中注册

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
        <!-- This entry makes ExampleLoggerInitializer discoverable. -->
        <meta-data
            android:name="com.angle.android.startup.ContextManagerInitializer"
            android:value="androidx.startup" />
        <meta-data
            android:name="com.angle.android.startup.ContextManagerInitializerJava"
            android:value="androidx.startup" />
    </provider>

这里因为一个java一个kotlin,所以这里我直接注册了两个.其实要注册多个的话,按照上面的方式进行注册就好了.

3. Startup的一些特殊的配置

3.1 禁用单个组件初始化

tools:node="remove"

在的标签中添加以上的代码.就可以禁用这个初始化. 如果把这个添加到的时候就可以禁止所有的初始化.

那么问题又来了?我要怎么进行初始化呢?其实startup给我们提供了一个手动的初始化代码.

kotlin代码

AppInitializer.getInstance(context)
.initializeComponent(ContextManagerInitializer::class.java)

java代码

AppInitializer.getInstance(context)
.initializeComponent(ContextManagerInitializerJava.class);

那里使用就在哪里初始化.其实也就是延迟初始化.


以上呢就是关于Startup的使用,其实还是很简单的.没有什么高深的内容.其实关于这个初始化组件到底能对启动有多少提升,其实你可以在自己的项目中添加相应的System.currentTimeMillis()进行尝试一下.效果还是挺明显的.我们之前的项目启动都能到1000ms,优化之后在100us之内.所以还是可以替换到项目中的.

在写这篇博客的时候我突发出一个灵感.如果我创建一个类,把类型定义成Object,那么岂不是我就创建一个初始化的类就好了,岂不是不用创建多个.但是我觉得这个想法有点另类.所以就不在这里给你们展示了...