Android Jetpack架构组件(十)— StartUp

一、StartUp简介

应用程序启动库提供了一种在应用程序启动时初始化组件的简单、高效的方法。库开发人员和应用程序开发人员都可以使用StartUp来简化启动序列并显式设置初始化顺序。
StartUp允许您定义共享单个内容提供程序的组件初始化程序,而不是为每个需要初始化的组件定义单独的content provider。这可以显著缩短应用程序启动时间。

简单的说就是通过一个公共的content provider来集中管理需要初始化的组件,从而提高应用的启动速度。

二、StartUp使用

1、在build.gradle中添加所需依赖

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

2、创建初始化入口

每一个需要初始化的组件我们需要创建一个class去实现Initializer<T>接口

class AModuleInitializer : Initializer<AModule> {
    override fun create(context: Context): ASdk {
        Log.i("xjm","AModuleInitializer create()方法执行" )
        return AModule.getInstance()
    }
    override fun dependencies(): MutableList<Class<out Initializer<*>>> {
        Log.i("xjm","AModuleInitializer dependencies()方法执行" )
        return mutableListOf()
    }
}

只需实现两个方法:

  • create ()方法
    包含初始化组件所需的所有操作,并返回T的实例。
  • dependencies()方法
    返回的是一个Initializer<T>的list,这个集合当中包含了当前的Initializer<T>所依赖的其他的Initializer<T>,由此可见该方法的作用是让我们可以控制在程序启动时的组件的初始化顺序。(即需要依赖的Initializer初始化后,才会创建自己)

两个方法执行顺序为dependencies() -> create ()

3、启动StartUp

StartUp为我们提供了两种方式来启动,一种是自动启动,一种是手动调用启动。

1.自动启动

我们只需要在AndroidManifest中对InitializationProvider添加对应声明:

  • 声明其原理中真正使用的ContentProvider类androidx.startup.InitializationProvider
  • authorities要携带${applicationId}来避免与其他App产生冲突
  • 要在这个provider下声明meta-data;
    Startup会去找自己Provider下声明的第一个meta-data所对应的类,来对他进行初始化,如果他声明了他有依赖项,那么他的依赖项也会被初始化。顺序寻找meta-data对应的类并依次初始化。

声明ContentProvider类其基本原理就是依靠ContentProvider的onCreate会在应用初始化时被自动调用;

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <meta-data
        android:name="com.alanmyapplication. CModuleInitializer"
        android:value="androidx.startup" />
    <meta-data
        android:name="com.alan.myapplication.DModuleInitializer"
        android:value="androidx.startup"
        tools:node="remove"/>
</provider>
meta-data标签:
  • name:是Initializer的路径
  • value:必须为androidx.startup才可以被收集到,后续的触发是按照在Manifest中声明的顺序进行的。
依赖链声明
  • 若存在依赖关系C -> B -> A,则只需要声明C即可,因为A和B可以通过C的dependencies()方法链式调用进行初始化。A,B,C的执行顺序为:
C的dependencies() -> 
B的dependencies() -> 
A的dependencies() -> 
A的create () -> 
B的create () -> 
C的create () -> 
  • 若A,B,C之间不存在依赖关系的话,则需要对每一个对应的Initializer进行声明。而A,B,C的执行顺序则与我们的声明顺序保持一致。

需要注意的是:
会使用Map mInitialized来确保每个类只会被初始化一次,而通过临时的initializing确保在依赖关系中不允许循环依赖

2.手动调用启动
(1)、声明中关闭自动初始化

tools:node="remove"这个标签的作用是为了防止在其他引用的三方库中有对相同组件的一个初始化,保证该组件的自动初始化真正的被关闭。

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup"
    android:exported="false"
    tools:node="merge">
     <meta-data
        android:name="com.alan.myapplication.DModuleInitializer"
        android:value="androidx.startup"
        tools:node="remove"/>
</provider>

关闭startup的所有组件的自动初始化,除了在<meta-data>标签上一个个添加之外,还可以统一关闭:

<provider android:name="androidx.startup.InitializationProvider"
    android:authorities="${applicationId}.androidx-startup" 
    tools:node="remove"/>
(2)、在代码中进行初始化
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        //手动启动初始化
        AppInitializer.getInstance(this).initializeComponent(DModuleInitializer::class.java)
    }
}

三、源代码

AppInitializer类

public final class AppInitializer {
    private static AppInitializer sInstance;

    /**
     * Guards app initialization.
     */
    private static final Object sLock = new Object();

    @NonNull
    final Map<Class<?>, Object> mInitialized;

    @NonNull
    final Context mContext;

    /**
     * Creates an instance of {@link AppInitializer}
     *
     * @param context The application context
     */
    AppInitializer(@NonNull Context context) {
        mContext = context.getApplicationContext();
        mInitialized = new HashMap<>();
    }

    /**
     * @param context The Application {@link Context}
     * @return The instance of {@link AppInitializer} after initialization.
     */
    @NonNull
    @SuppressWarnings("UnusedReturnValue")
    public static AppInitializer getInstance(@NonNull Context context) {
        synchronized (sLock) {
            if (sInstance == null) {
                sInstance = new AppInitializer(context);
            }
            return sInstance;
        }
    }
                ...
}

Map<Class<?>, Object> 用map去存储已经被初始化过的组件。

参考:Jetpack StartUp详解

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容