Android Jetpack系列之App Startup使用詳解
定義
- 一個(gè)可以用于加速App啟動(dòng)速度的庫(kù);
- 提供在 App 啟動(dòng)時(shí)初始化組件簡(jiǎn)單、高效的方法,可以使用 App Startup 顯示的設(shè)置初始化順序;
- 提供了一個(gè) ContentProvider 來運(yùn)行所有依賴項(xiàng)的初始化,避免每個(gè)第三方庫(kù)單獨(dú)使用 ContentProvider 進(jìn)行初始化,從而提高了應(yīng)用的程序的啟動(dòng)速度;
解決了什么問題
- 如果你在項(xiàng)目當(dāng)中引入了非常多的第三方庫(kù),那么Application中的代碼就可能會(huì)變成這個(gè)樣子(這還只是我們實(shí)際項(xiàng)目的部分代碼):
class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
CommonModule.init(this);
XCrash.init(this, new XCrash.InitParameters());
initQbSdk(this);
initRetrofit();
initDialogSetting();
initBugly();
initWeChat();
initUmeng();
initDoKit();
initNIM();
}
...
}- 有些更加聰明的庫(kù)設(shè)計(jì)者,想到可以借助ContentProvider自動(dòng)調(diào)用初始化接口,從而避免顯示的初始化:
//1. 繼承 ContentProvider,在onCreate中初始化
class MyProvider : ContentProvider() {
override fun onCreate(): Boolean {
context?.let {
//ContentProvider中也可以取得Context
LjyToastUtil.getInstance().init(it)
}
return true
}
//其他方法用不到,直接return null 或 return -1 即可
...
}
//2. ContentProvider是四大組件之一,需要在AndroidManifest.xml文件中進(jìn)行注冊(cè)
<application ...>
...
<provider
android:name=".MyProvider"
//authorities的值沒有固定要求,但要保證該值在整個(gè)手機(jī)上是唯一的,所以通常會(huì)使用${applicationId}作為前綴,以防止和其他應(yīng)用程序沖突
android:authorities="${applicationId}.myProvider"
android:exported="false" />
</application>
//3. 自定義的MyProvider在什么時(shí)候執(zhí)行呢? 調(diào)用流程如下:
Application.attachBaseContext() -> ContentProvider.onCreate() -> Application.onCreate()
//這是在冷啟動(dòng)階段自動(dòng)運(yùn)行初始化的,來看一下 Android 10 系統(tǒng)源碼
private void handleBindApplication(AppBindData data) {
...
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
// 創(chuàng)建ContentProvider
installContentProviders(app, data.providers);
}
}
...
try {
// 調(diào)用調(diào)用 Application 的 OnCreate 方法
mInstrumentation.callApplicationOnCreate(app);
} catch (Exception e) {
...
}
...
}- 此方案的缺點(diǎn):ContentProvider會(huì)增加許多額外的耗時(shí), ContentProvider是Android四大組件之一,這個(gè)組件相對(duì)來說是比較重量級(jí)的, 也就是說,本來我的初始化操作可能是一個(gè)非常輕量級(jí)的操作,依賴于ContentProvider之后就變成了一個(gè)重量級(jí)的操作了;
如何解決問題
- 鑒于前兩者的缺點(diǎn),Google推出了App Startup
- App Startup是如何解決問題的呢?它可以將所有用于初始化的ContentProvider合并成一個(gè),從而使App的啟動(dòng)速度變得更快。
使用方法
1. 引入AppStartup依賴
implementation "androidx.startup:startup-runtime:1.1.0-alpha01"
2. 實(shí)現(xiàn)App Startup庫(kù)的Initializer接口
定義一個(gè)用于執(zhí)行初始化的類,并實(shí)現(xiàn)App Startup庫(kù)的Initializer接口
class LjyToastInitializer : Initializer<Unit> {
//在create方法中執(zhí)行要初始化的代碼
override fun create(context: Context) {
LjyToastUtil.getInstance().init(context)
}
//dependencies方法用于配置當(dāng)前LjyToastInitializer是否還依賴于其他Initializer
//有的話在此配置,沒有就return emptyList()即可
override fun dependencies(): List<Class<out Initializer<*>>> {
return emptyList()
}
}3. 在庫(kù)的AndroidManifest.xml中配置MyInitializer
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.jinyang.jetpackdemo.LjyToastInitializer"
android:value="androidx.startup" />
</provider>- 當(dāng)App啟動(dòng)的時(shí)候會(huì)自動(dòng)執(zhí)行App Startup庫(kù)中內(nèi)置的ContentProvider,并在它的ContentProvider中會(huì)搜尋所有注冊(cè)的Initializer,然后逐個(gè)調(diào)用它們的create()方法來進(jìn)行初始化操作;
延遲初始化
- 如果不希望在啟動(dòng)的時(shí)候自動(dòng)初始化某個(gè)庫(kù),而是想要在特定的時(shí)機(jī)手動(dòng)初始化,這要怎么辦呢?
- 首先通過分析源碼,找到該庫(kù)初始化的Initializer的全路徑類名
- 在項(xiàng)目的AndroidManifest.xml當(dāng)中加入如下配置:
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="com.jinyang.jetpackdemo.LjyToastInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>- 禁用單個(gè)庫(kù)就在meta-data中加入tools:node="remove"
- 禁用所有庫(kù)就是在provider標(biāo)簽中加入tools:node="remove"
- 然后在需要的地方去手動(dòng)的初始化
AppInitializer.getInstance(this)
.initializeComponent(LjyToastInitializer::class.java)- 延遲初始化也是非常有用的,可以減少 App 的啟動(dòng)時(shí)間,提高啟動(dòng)速度。
以上就是Android Jetpack系列之App Startup使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Android Jetpack App Startup的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android實(shí)現(xiàn)界面的自動(dòng)跳轉(zhuǎn)功能
界面自動(dòng)跳轉(zhuǎn)是指在應(yīng)用啟動(dòng)或某個(gè)特定界面顯示后,經(jīng)過預(yù)定的時(shí)間或者滿足某些條件后,自動(dòng)跳轉(zhuǎn)到另一個(gè)目標(biāo)界面,本文小編給大家講解了Android實(shí)現(xiàn)界面的自動(dòng)跳轉(zhuǎn)功能,感興趣的小伙伴跟著小編一起來看看吧2025-04-04
Android開發(fā)實(shí)現(xiàn)拍照功能的方法實(shí)例解析
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)拍照功能的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了Android拍照功能的具體實(shí)現(xiàn)步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03
Android小程序?qū)崿F(xiàn)個(gè)人信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Android小程序?qū)崿F(xiàn)個(gè)人信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05
Android學(xué)習(xí)筆記之ContentProvider和Uri詳解
本篇文章主要介紹了Android學(xué)習(xí)筆記之ContentProvider和Uri詳解,對(duì)于學(xué)習(xí)Android的朋友具有一定的參考價(jià)值,有需要可以可以了解一下。2016-11-11
Android實(shí)現(xiàn)頁面滑動(dòng)切換動(dòng)畫
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)頁面滑動(dòng)切換動(dòng)畫,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12
Android studio實(shí)現(xiàn)菜單效果
這篇文章主要為大家詳細(xì)介紹了Android studio實(shí)現(xiàn)菜單效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10
Android BroadcastReceiver實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)實(shí)時(shí)監(jiān)聽
這篇文章主要為大家詳細(xì)介紹了Android BroadcastReceiver實(shí)現(xiàn)網(wǎng)絡(luò)狀態(tài)實(shí)時(shí)監(jiān)聽,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android?studio實(shí)現(xiàn)簡(jiǎn)單計(jì)算器的編寫
這篇文章主要為大家詳細(xì)介紹了Android?studio實(shí)現(xiàn)簡(jiǎn)單計(jì)算器的編寫,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
Android中WebView實(shí)現(xiàn)點(diǎn)擊超鏈接啟動(dòng)QQ的方法
這篇文章主要給大家介紹了在Android中WebView如何實(shí)現(xiàn)點(diǎn)擊超鏈接啟動(dòng)QQ的方法,文中給出了詳細(xì)的示例代碼,相信對(duì)大家的學(xué)習(xí)或者工作具有一定的參考價(jià)值,需要的朋友們下面來一起看看吧。2017-04-04

