Android Jetpack系列之App Startup使用詳解
定義
- 一個(gè)可以用于加速App啟動(dòng)速度的庫(kù);
- 提供在 App 啟動(dòng)時(shí)初始化組件簡(jiǎn)單、高效的方法,可以使用 App Startup 顯示的設(shè)置初始化順序;
- 提供了一個(gè) ContentProvider 來(lái)運(yùn)行所有依賴項(xiàng)的初始化,避免每個(gè)第三方庫(kù)單獨(dú)使用 ContentProvider 進(jìn)行初始化,從而提高了應(yīng)用的程序的啟動(dòng)速度;
解決了什么問(wèn)題
- 如果你在項(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的值沒(méi)有固定要求,但要保證該值在整個(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)行初始化的,來(lái)看一下 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ì)來(lái)說(shuō)是比較重量級(jí)的, 也就是說(shuō),本來(lái)我的初始化操作可能是一個(gè)非常輕量級(jí)的操作,依賴于ContentProvider之后就變成了一個(gè)重量級(jí)的操作了;
如何解決問(wèn)題
- 鑒于前兩者的缺點(diǎn),Google推出了App Startup
- App Startup是如何解決問(wèn)題的呢?它可以將所有用于初始化的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 //有的話在此配置,沒(méi)有就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()方法來(lái)進(jìn)行初始化操作;
延遲初始化
- 如果不希望在啟動(dòng)的時(shí)候自動(dòng)初始化某個(gè)庫(kù),而是想要在特定的時(shí)機(jī)手動(dòng)初始化,這要怎么辦呢?
- 首先通過(guò)分析源碼,找到該庫(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音視頻開(kāi)發(fā)只硬件解碼組件MediaCodec講解
在Android開(kāi)發(fā)中提供了實(shí)現(xiàn)音視頻編解碼工具M(jìn)ediaCodec,針對(duì)對(duì)應(yīng)音視頻解碼類型通過(guò)該類創(chuàng)建對(duì)應(yīng)解碼器就能實(shí)現(xiàn)對(duì)數(shù)據(jù)進(jìn)行解碼操作。本文通過(guò)示例詳細(xì)講解了MediaCodec的使用,需要的可以參考一下2023-01-01Android 中通過(guò)實(shí)現(xiàn)線程更新Progressdialog (對(duì)話進(jìn)度條)
這篇文章主要介紹了Android 中通過(guò)實(shí)現(xiàn)線程更新Progressdialog (對(duì)話進(jìn)度條)的相關(guān)資料,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11Android調(diào)試神器stetho使用詳解和改造
今天小編就為大家分享一篇關(guān)于Android調(diào)試神器stetho使用詳解和改造,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02Android將camera獲取到的YuvData在jni中轉(zhuǎn)化為Mat方法
今天小編就為大家分享一篇Android將camera獲取到的YuvData在jni中轉(zhuǎn)化為Mat方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08解決Android Studio電腦不支持HAXM的問(wèn)題
這篇文章主要介紹了Android Studio電腦不支持HAXM的問(wèn)題及解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2020-03-03