Android啟動(dòng)初始化方案App StartUp的應(yīng)用詳解
StartUp是為了App的啟動(dòng)提供的一套簡(jiǎn)單、高效的初始化方案。
ContentProvider中初始化
在項(xiàng)目中會(huì)需要用到很多的第三方庫(kù),而很多第三方庫(kù)都提供了顯示的調(diào)用初始化接口,需要在Application中進(jìn)行初始化,并獲取到Application的Context。
于是乎,Application中的代碼就可能會(huì)變成這個(gè)樣子:
class MyApplication : Application() { override fun onCreate() { super.onCreate() A.initialize(this) B.initialize(this) C.initialize(this) ... } ... }
隨著引入的第三方庫(kù)越來(lái)越多,Application中的代碼也是越來(lái)越龐大。
于是乎,有些更加聰明的庫(kù)設(shè)計(jì)者,他們想到了一種非常巧妙的辦法來(lái)避免顯示的調(diào)用初始化接口,而是可以自動(dòng)調(diào)用初始化接口,這種辦法就是借助ContentProvider。
ContentProvider作為Android四大組件之一,其主要作用是跨應(yīng)用程序共享數(shù)據(jù)。
然而這些第三方庫(kù)并沒(méi)有打算使用ContentProvider來(lái)跨應(yīng)用程序共享數(shù)據(jù),只是準(zhǔn)備使用它拿到Context進(jìn)行初始化而已。在APP的啟動(dòng)流程中,有一步就是要執(zhí)行到程序中所有注冊(cè)過(guò)的ContentProvider的onCreate方法,所以這些第三方庫(kù)的初始化就默默自動(dòng)完成了。
這種設(shè)計(jì)方式可以將庫(kù)的用法進(jìn)一步簡(jiǎn)化,不需要主動(dòng)去調(diào)用初始化接口,而是將這個(gè)工作在背后悄悄自動(dòng)完成了,給集成庫(kù)的開(kāi)發(fā)者們帶來(lái)了很大的便利。很多庫(kù)都用到了這種方法,比如Facebook,F(xiàn)irebase。
但是呢,看上去如此巧妙的技術(shù)方案,有一個(gè)很大的缺點(diǎn)就是,ContentProvider會(huì)增加許多額外的耗時(shí)。因?yàn)椴煌膸?kù)就定義了不同的ContentProvider類,多了這么多ContentProvider,ContentProvider作為四大組件之一,啟動(dòng)也是耗時(shí)的,自然也就增加App啟動(dòng)消耗的時(shí)間了。
這時(shí)候就需要App Startup來(lái)對(duì)此情況進(jìn)行優(yōu)化了。
App Startup
首先來(lái)看一下官網(wǎng)對(duì)于Startup的簡(jiǎn)介:
The App Startup library provides a straightforward, performant way to initialize components at application startup. Both library developers and app developers can use App Startup to streamline startup sequences and explicitly set the order of initialization.
Instead of defining separate content providers for each component you need to initialize, App Startup allows you to define component initializers that share a single content provider. This can significantly improve app startup time.
主要說(shuō)到了兩點(diǎn)特性:
- 明確設(shè)置初始化順序
- 共享單個(gè)ContentProvider
其實(shí),App Startup內(nèi)部也是創(chuàng)建了一個(gè)ContentProvider,并提供了一套用于初始化的標(biāo)準(zhǔn)。然后對(duì)于其他第三方庫(kù)來(lái)說(shuō),就不需要再自己創(chuàng)建ContentProvider了,都按Startup這套標(biāo)準(zhǔn)進(jìn)行實(shí)現(xiàn)就行了。同時(shí)Startup還提供了可以設(shè)置初始化順序。
App Startup使用
首先,引入庫(kù):
implementation 'androidx.startup:startup-runtime:1.1.1'
然后定義一個(gè)用于執(zhí)行初始化的Initializer,并實(shí)現(xiàn)App Startup庫(kù)的Initializer接口:
class ARouterInitializer : Initializer<String> { override fun create(context: Context): String { ARouter.init(context.applicationContext as Application) return "ARouterInit" } override fun dependencies(): List<Class<out Initializer<*>>> { return emptyList() } }
實(shí)現(xiàn)Initializer接口要求重寫(xiě)兩個(gè)方法,在create()方法中可以進(jìn)行初始化操作,這里以ARouter發(fā)初始化為例。
dependencies()方法表示,當(dāng)前的初始化是否還依賴于其他的Initializer,如果有的話,就在這里進(jìn)行配置,App Startup會(huì)保證先初始化依賴的Initializer,然后才會(huì)初始化當(dāng)前,這樣就可以設(shè)置初始化順序了。當(dāng)然,絕大多數(shù)的情況下,初始化操作都是不會(huì)依賴于其他Initializer的,所以通常直接返回一個(gè)emptyList()就可以了。
最后,在AndroidManifest.xml中進(jìn)行配置,這里需要嚴(yán)格按照Startup的配置規(guī)范:
<provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.example.base.ARouterInitializer" android:value="androidx.startup" /> </provider>
只有meta-data中的android:name部分需要指定成自定義的Initializer的全路徑類名,其他部分都是不能修改的,否則App Startup庫(kù)可能會(huì)無(wú)法正常工作。
tools:node="merge"標(biāo)簽就是用來(lái)合并所有申明了InitializationProvider的ContentProvider。
延遲初始化
如果不希望初始化在應(yīng)用啟動(dòng)的時(shí)候自動(dòng)初始化,App Startup也是提供了手動(dòng)調(diào)用初始化的方法。
<!-- 禁用所有InitializationProvider組件初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" tools:node="remove" /> <!-- 禁用單個(gè)InitializationProvider組件初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" android:exported="false" tools:node="merge"> <meta-data android:name="com.example.base.ARouterInitializer" tools:node="remove" /> </provider>
使用tools:node="remove"標(biāo)簽,這個(gè)標(biāo)簽用于告訴manifest merger tool,在最后打包成APK時(shí),將所有該名稱的節(jié)點(diǎn)全部刪除??梢越盟蠭nitializationProvider組件初始化,也可以禁用單個(gè)InitializationProvider組件初始化。
AppInitializer.getInstance(this).initializeComponent(ARouterInitializer::class.java)
然后再手動(dòng)調(diào)用App Startup提供的初始化方法。
到此這篇關(guān)于Android啟動(dòng)初始化方案App StartUp的應(yīng)用詳解的文章就介紹到這了,更多相關(guān)Android App StartUp內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android實(shí)現(xiàn)相機(jī)拍攝、選擇、圖片裁剪功能
自定義控件,重寫(xiě)ImageView 功能實(shí)現(xiàn):點(diǎn)擊圓形頭像之后可以實(shí)現(xiàn)相冊(cè)上傳或者開(kāi)啟相機(jī),然后把得到的圖片經(jīng)過(guò)剪裁,把剪裁過(guò)的圖片設(shè)置為頭像的背景圖,需要的朋友可以參考下2016-09-09Android adb命令中pm工具的作用及用法說(shuō)明
這篇文章主要介紹了Android adb命令中pm工具的作用及用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08解決Android Studio Log.v和Log.d不顯示的問(wèn)題
這篇文章主要介紹了解決Android Studio Log.v和Log.d不顯示的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-08-08Android NDK開(kāi)發(fā)詳細(xì)介紹
本文主要介紹Android NDK開(kāi)發(fā),這里詳細(xì)整理了相關(guān)資料并介紹 NDK的知識(shí)和開(kāi)發(fā)流程及簡(jiǎn)單示例代碼,幫助大家學(xué)習(xí),有需要的小伙伴可以參考下2016-09-09Android應(yīng)用開(kāi)發(fā)中Fragment的靜態(tài)加載與動(dòng)態(tài)加載實(shí)例
這篇文章主要介紹了Android應(yīng)用開(kāi)發(fā)中Fragment的靜態(tài)加載與動(dòng)態(tài)加載實(shí)例,例子中包括動(dòng)態(tài)的添加更新以及刪除Fragment等操作,很有借鑒意義,需要的朋友可以參考下2016-02-02Android仿今日頭條APP實(shí)現(xiàn)下拉導(dǎo)航選擇菜單效果
這篇文章主要為大家詳細(xì)介紹了Android仿今日頭條APP實(shí)現(xiàn)下拉導(dǎo)航選擇菜單效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06在android中ScrollView嵌套ScrollView解決方案
大家好,眾所周知,android里兩個(gè)相同方向的ScrollView是不能嵌套的,那要是有這樣的需求怎么辦,接下來(lái)為您介紹解決方法,感興趣的朋友可以了解下2013-01-01安卓輸入框被虛擬鍵盤(pán)擋住的問(wèn)題(微信開(kāi)發(fā))
這篇文章主要介紹了安卓輸入框被虛擬鍵盤(pán)擋住的問(wèn)題(微信開(kāi)發(fā))的相關(guān)資料,需要的朋友可以參考下2016-04-04