Android Jetpack 之 App Startup

       我们平常在项目开发中,会引入或多或少第三方sdk,引入时基本上都需要初始化,而大部分sdk初始化,都提倡在 Application的onCreate()里面初始化,比如下面:

class MyApplication:Application() {

    override fun onCreate() {
        super.onCreate()
        MySdk().init(this)
        MySdk1().init(this)
        MySdk2().init(this)
        MySdk3().init(this)
        Log.d("MyTest", "MyApplication  create")
    }

}

这样,随着项目开发,引入的第三方sdk肯定会越来越多,这样就会让Application里面做初始化的代码非常多非常臃肿,而且太多也会影响整个App的启动效率。那有没有一种方案,既可以让 Application不那么臃肿,又提高App的启动效率呢?

Jetpack 的 AppStartup

怎么用呢?很简单,就三步

1.引入依赖

2.实现 Initializer 接口

3.在AndroidManifest.xml的注册

扫描二维码关注公众号,回复: 11823082 查看本文章

1.引入依赖

dependencies {
    implementation "androidx.startup:startup-runtime:1.0.0-alpha02"
}

2.实现 Initializer 接口

class SdkInitializer : Initializer<Any> {

    override fun create(context: Context) {
        // init your sdk
        MySdk().init(context)
        Log.d("MyTest", "Initializer  create")
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        Log.d("MyTest", "Initializer  dependencies")
        return emptyList()
    }

}

3.在AndroidManifest.xml的注册

<provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <meta-data
                android:name="com.leo.dicaprio.myutilapp.startup.SdkInitializer"
                android:value="androidx.startup" />
</provider>

这里主要一下,AndroidManifest.xml注册的内容,只有 meta-data - name   可以更改,其他的地方最好不要改,也不需要改

就是这么简单。把需要初始化的sdk,都放在 Initializer 的 create()dependencies() 两个接口里面,具体放在哪个接口里呢?

如果你引入的sdk1,是不需要依赖其他的sdk2,那只需要把sdk1放进 create() 初始化即可,如下:

class SdkInitializer : Initializer<Any> {

    override fun create(context: Context) {
        // init your sdk
        MySdk1().init(context)
        Log.d("MyTest", "Initializer  create")
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        Log.d("MyTest", "Initializer  dependencies")
        // 如果没有需要初始化的sdk,返回 空列表即可
        return emptyList()
    }

}

如果你引入的sdk1,是需要依赖其他的sdk2,那需要把sdk2 放进 dependencies() 里面,再把sdk1放进 create() 初始化,

因为 dependencies()  先于 create()  回调,保证sdk2 先初始化, 如下:

SdkInitializer

class SdkInitializer : Initializer<Any> {

    override fun create(context: Context) {
        // init your sdk
        MySdk().init(context)
        Log.d("MyTest", "Initializer  create")
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        Log.d("MyTest", "Initializer  dependencies")
        return listOf(Sdk2Initializer::class.java)
    }

}

SdkInitializer2

class Sdk2Initializer : Initializer<Any> {

    override fun create(context: Context) {
        // init your sdk
        MySdk2().init(context)
        Log.d("MyTest", "Initializer  create2")
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        Log.d("MyTest", "Initializer  dependencies2")
        return emptyList()
    }

}

注意,只需要注册一个Initializer , Sdk2Initializer 不需要 在AndroidManifest.xml 注册了,否则会报错...

启动应用,我们看下日志:

/MyTest: Initializer  dependencies
/MyTest: Initializer  dependencies2
/MyTest: Initializer  create2
/MyTest: Initializer  create

看日志可得:先去初始化sdk2,再去初始化 sdk1

原理

上面只是说到如何使用,但是,它为啥能提高启动效率呢?先看下 Initializer 在 AndroidManifest.xml的注册,

        <provider
            android:name="androidx.startup.InitializationProvider"
            android:authorities="${applicationId}.androidx-startup"
            android:exported="false"
            tools:node="merge">
            <meta-data
                android:name="com.leo.dicaprio.myutilapp.startup.SdkInitializer"
                android:value="androidx.startup" />
        </provider>

其实,Initializer  就是一个 ContentProvider 。而 ContentProvider 的执行,是先于 Application的,流程如下:

一个应用程序的执行顺序是这个样子的。首先调用Application的attachBaseContext()方法,然后调用ContentProvider的onCreate()方法,接下来调用Application的onCreate()方法

我们把 sdk 的初始化 挪到 ContentProvider里面,先于Application,这样只是避免了 Application代码的臃肿,并没有看到提高啥效率了,因为该花多少时间去初始化,还得花多少时间。

然而,你们可记得?上面说过只需要注册一个 Initializer,不需要也不能注册多个 Initializer。其实AppStartup 之所以能提高效率正是在这里,不管你需要初始化多少个sdk,都只需要注册一个 Initializer(即:一个ContentProvider)。

很简单,注册的 ContentProvider 越多,ContentProvider启动 占用的时间就越多。但是只注册一个 ContentProvider,当然可以提高效率。

以上如有问题请留言指出,谢谢

猜你喜欢

转载自blog.csdn.net/Leo_Liang_jie/article/details/108404923