Android啟動初始化方案App StartUp的應(yīng)用詳解
StartUp是為了App的啟動提供的一套簡單、高效的初始化方案。
ContentProvider中初始化
在項目中會需要用到很多的第三方庫,而很多第三方庫都提供了顯示的調(diào)用初始化接口,需要在Application中進行初始化,并獲取到Application的Context。
于是乎,Application中的代碼就可能會變成這個樣子:
class MyApplication : Application() { override fun onCreate() { super.onCreate() A.initialize(this) B.initialize(this) C.initialize(this) ... } ... }
隨著引入的第三方庫越來越多,Application中的代碼也是越來越龐大。
于是乎,有些更加聰明的庫設(shè)計者,他們想到了一種非常巧妙的辦法來避免顯示的調(diào)用初始化接口,而是可以自動調(diào)用初始化接口,這種辦法就是借助ContentProvider。
ContentProvider作為Android四大組件之一,其主要作用是跨應(yīng)用程序共享數(shù)據(jù)。
然而這些第三方庫并沒有打算使用ContentProvider來跨應(yīng)用程序共享數(shù)據(jù),只是準(zhǔn)備使用它拿到Context進行初始化而已。在APP的啟動流程中,有一步就是要執(zhí)行到程序中所有注冊過的ContentProvider的onCreate方法,所以這些第三方庫的初始化就默默自動完成了。
這種設(shè)計方式可以將庫的用法進一步簡化,不需要主動去調(diào)用初始化接口,而是將這個工作在背后悄悄自動完成了,給集成庫的開發(fā)者們帶來了很大的便利。很多庫都用到了這種方法,比如Facebook,F(xiàn)irebase。
但是呢,看上去如此巧妙的技術(shù)方案,有一個很大的缺點就是,ContentProvider會增加許多額外的耗時。因為不同的庫就定義了不同的ContentProvider類,多了這么多ContentProvider,ContentProvider作為四大組件之一,啟動也是耗時的,自然也就增加App啟動消耗的時間了。
這時候就需要App Startup來對此情況進行優(yōu)化了。
App Startup
首先來看一下官網(wǎng)對于Startup的簡介:
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.
主要說到了兩點特性:
- 明確設(shè)置初始化順序
- 共享單個ContentProvider
其實,App Startup內(nèi)部也是創(chuàng)建了一個ContentProvider,并提供了一套用于初始化的標(biāo)準(zhǔn)。然后對于其他第三方庫來說,就不需要再自己創(chuàng)建ContentProvider了,都按Startup這套標(biāo)準(zhǔn)進行實現(xiàn)就行了。同時Startup還提供了可以設(shè)置初始化順序。
App Startup使用
首先,引入庫:
implementation 'androidx.startup:startup-runtime:1.1.1'
然后定義一個用于執(zhí)行初始化的Initializer,并實現(xiàn)App Startup庫的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() } }
實現(xiàn)Initializer接口要求重寫兩個方法,在create()方法中可以進行初始化操作,這里以ARouter發(fā)初始化為例。
dependencies()方法表示,當(dāng)前的初始化是否還依賴于其他的Initializer,如果有的話,就在這里進行配置,App Startup會保證先初始化依賴的Initializer,然后才會初始化當(dāng)前,這樣就可以設(shè)置初始化順序了。當(dāng)然,絕大多數(shù)的情況下,初始化操作都是不會依賴于其他Initializer的,所以通常直接返回一個emptyList()就可以了。
最后,在AndroidManifest.xml中進行配置,這里需要嚴(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庫可能會無法正常工作。
tools:node="merge"標(biāo)簽就是用來合并所有申明了InitializationProvider的ContentProvider。
延遲初始化
如果不希望初始化在應(yīng)用啟動的時候自動初始化,App Startup也是提供了手動調(diào)用初始化的方法。
<!-- 禁用所有InitializationProvider組件初始化 --> <provider android:name="androidx.startup.InitializationProvider" android:authorities="${applicationId}.androidx-startup" tools:node="remove" /> <!-- 禁用單個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)簽,這個標(biāo)簽用于告訴manifest merger tool,在最后打包成APK時,將所有該名稱的節(jié)點全部刪除??梢越盟蠭nitializationProvider組件初始化,也可以禁用單個InitializationProvider組件初始化。
AppInitializer.getInstance(this).initializeComponent(ARouterInitializer::class.java)
然后再手動調(diào)用App Startup提供的初始化方法。
到此這篇關(guān)于Android啟動初始化方案App StartUp的應(yīng)用詳解的文章就介紹到這了,更多相關(guān)Android App StartUp內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決Android Studio Log.v和Log.d不顯示的問題
這篇文章主要介紹了解決Android Studio Log.v和Log.d不顯示的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Android應(yīng)用開發(fā)中Fragment的靜態(tài)加載與動態(tài)加載實例
這篇文章主要介紹了Android應(yīng)用開發(fā)中Fragment的靜態(tài)加載與動態(tài)加載實例,例子中包括動態(tài)的添加更新以及刪除Fragment等操作,很有借鑒意義,需要的朋友可以參考下2016-02-02Android仿今日頭條APP實現(xiàn)下拉導(dǎo)航選擇菜單效果
這篇文章主要為大家詳細(xì)介紹了Android仿今日頭條APP實現(xiàn)下拉導(dǎo)航選擇菜單效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-06-06在android中ScrollView嵌套ScrollView解決方案
大家好,眾所周知,android里兩個相同方向的ScrollView是不能嵌套的,那要是有這樣的需求怎么辦,接下來為您介紹解決方法,感興趣的朋友可以了解下2013-01-01