通過(guò)這篇文章你將學(xué)習(xí)到以下內(nèi)容:
App Startup 是什么?
App Startup 為我們解決了什么問(wèn)題?
為什么無(wú)論是 Google 還是第三方庫(kù),初始化時(shí)都會(huì)在 ContentProvider 里面進(jìn)行初始化?
在 ContentProvider 里初始化會(huì)帶來(lái)什么性能問(wèn)題?
ContentProvider 啟動(dòng)順序源碼分析?
如何正確使用 App Startup?
自動(dòng)初始化。
手動(dòng)初始化(也是延遲初始化)。
1.App Startup 是什么?
來(lái)自 Google 文檔:App Startup 是 Android Jetpack 最新成員,提供了在 App 啟動(dòng)時(shí)初始化組件簡(jiǎn)單、高效的方法,無(wú)論是 library 開(kāi)發(fā)人員還是 App 開(kāi)發(fā)人員都可以使用 App Startup 顯示的設(shè)置初始化順序。
簡(jiǎn)單的說(shuō)就是 App Startup 提供了一個(gè) ContentProvider 來(lái)運(yùn)行所有依賴(lài)項(xiàng)的初始化,避免每個(gè)第三方庫(kù)單獨(dú)使用 ContentProvider 進(jìn)行初始化,從而提高了應(yīng)用的程序的啟動(dòng)速度。

上圖表示現(xiàn)在我們有三個(gè)庫(kù)分別 LibraryA、LibraryB、和 LibraryC 它們使用自己的 ContentProviders 進(jìn)行初始化。 而 App Startup 提供了一個(gè) ContentProvider 來(lái)運(yùn)行所有依賴(lài)項(xiàng)的初始化(LibraryA、LibraryB、和 LibraryC),如下圖所示。

2.AndroidX App Startup 為我們解決了什么問(wèn)題?
剛才我們說(shuō)到無(wú)論是 Google 提供的庫(kù)還是第三方庫(kù),App 啟動(dòng)運(yùn)行時(shí)會(huì)初始化一些邏輯,它們?yōu)榱朔奖汩_(kāi)發(fā)者使用,避免開(kāi)發(fā)者手動(dòng)調(diào)用,使用 ContentProvider 進(jìn)行初始化,例如 WorkManager 在應(yīng)用啟動(dòng)時(shí)使用 ContentProvider 進(jìn)行初始化,我們來(lái)看一下 WorkManager 的源碼,先來(lái)看一下 AndroidManifest.xml 文件內(nèi)容。

如上所見(jiàn),我們可以看到在 AndroidManifest.xml 文件內(nèi)定義了一個(gè)名為 WorkManagerInitializer 的 ContentProvider,我來(lái)看看 WorkManagerInitializer 里面都做了什么。

如上所見(jiàn)其實(shí)就是在 WorkManagerInitializer 的 onCreate() 方法里面,使用默認(rèn)配置初始化 WorkManager。
我們也來(lái)模仿 WorkManager 寫(xiě)一個(gè) Demo,這里只貼出部分代碼,更多信息查看 GitHub 上的 AppStartupSimple下面的 ContentProvider 模塊。

在 AndroidManifest.xml 文件中注冊(cè) WorkContentProvider。

運(yùn)行 App 日志如下所示。

假設(shè)你的 App 有很多類(lèi)似于 WorkManager 這樣的庫(kù),都在 ContentProvider 里面進(jìn)行一些初始化工作,在 App 啟動(dòng)時(shí)運(yùn)行多個(gè) ContentProvider,這樣會(huì)帶來(lái)一些問(wèn)題:
多個(gè) ContentProvider 會(huì)增加了 App 啟動(dòng)運(yùn)行的時(shí)間。
ContentProvider 的 onCreate 方法會(huì)先于 Application 的 OnCreate 方法執(zhí)行,這是在冷啟動(dòng)階段自動(dòng)運(yùn)行初始化的,來(lái)看一下 Android 10 系統(tǒng)源碼。

這是在 App 冷啟動(dòng)時(shí)自動(dòng)運(yùn)行初始化的,這樣只會(huì)增加 App 的加載時(shí)間,用戶希望 App 加載得快,啟動(dòng)慢會(huì)帶來(lái)糟糕的用戶體驗(yàn),AndroidX App Startup 正是為了解決這個(gè)問(wèn)題而出現(xiàn)的。
3.如何正確使用 AndroidX App Startup?
使用 AndroidX App Startup 來(lái)運(yùn)行所有依賴(lài)項(xiàng)的初始化有兩種方式:
自動(dòng)初始化。
手動(dòng)初始化(也是延遲初始化)。
具體可以查看 GitHub 上的 AppStartupSimple 下面的 Startup-Library 模塊相關(guān)代碼。
自動(dòng)初始化

實(shí)現(xiàn) Initializer 接口,并重寫(xiě)兩個(gè)方法,來(lái)初始化組件。

create(Context): 這里進(jìn)行組件初始化工作。
dependencies(): 返回需要初始化的列表,同時(shí)設(shè)置 App 啟動(dòng)時(shí)依賴(lài)庫(kù)運(yùn)行的順序,假設(shè) LibaryC 依賴(lài)于 LibaryB,LibaryB 依賴(lài)于 LibaryA,App 啟動(dòng)運(yùn)行時(shí),會(huì)先運(yùn)行 LibaryA 然后運(yùn)行 LibaryB 最后運(yùn)行 LibaryC。

在 AndroidManifest.xml 文件中注冊(cè) InitializationProvider。

App 啟動(dòng)的時(shí) App Startup 會(huì)讀取 AndroidManifest.xml 文件里面的 InitializationProvider 下面的 <meta-data> 聲明要初始化的組件,完成自動(dòng)初始化工作。
手動(dòng)初始化(也是延遲初始化)
在 build.gradle 文件內(nèi)添加依賴(lài),和上文一樣。
創(chuàng)建一個(gè)類(lèi) LibaryD 實(shí)現(xiàn) Initializer 接口,并重寫(xiě)兩個(gè)方法,來(lái)初始化組件,和上文一樣。

只需要在 <meta-data> 標(biāo)簽內(nèi)添加 tools:node="remove" 清單合并工具會(huì)將它從清單文件中刪除。 在需要的地方進(jìn)行初始化,調(diào)用以下代碼進(jìn)行初始化。

如果組件初始化之后,再次調(diào)用 AppInitializer.initializeComponent() 方法不會(huì)再次初始化。
手動(dòng)初始化(也是延遲初始化)是非常有用的,組件不需要在 App 啟動(dòng)時(shí)運(yùn)行,只需要在需要它地方運(yùn)行,可以減少 App 的啟動(dòng)時(shí)間,提高啟動(dòng)速度。
總結(jié)
這篇文章主要介紹了以下內(nèi)容:
ContentProvider 啟動(dòng)順序源碼分析。
App Startup 是 Jetpack 的新成員,是為了解決因 App 啟動(dòng)時(shí)運(yùn)行多個(gè) ContentProvider 會(huì)增加 App 的啟動(dòng)時(shí)間的問(wèn)題。
使用了一個(gè) InitializationProvider 管理多個(gè)依賴(lài)項(xiàng),消除了每個(gè)庫(kù)單獨(dú)使用 ContentProvider 成本,減少初始化時(shí)間。
App Startup 允許你自定義組件初始化順序。
App Startup 可以自動(dòng)初始化 AndroidManifest.xml 文件中 InitializationProvider 下面的 <meta-data> 聲明要初始化的組件。
App Startup 提供了一種延遲初始化組件的方法,減少 App 初始化時(shí)間。
了解更多干貨內(nèi)容可以添加我的q峮 1080621881 。