即學(xué)即用Android Jetpack - Startup

技術(shù)不止章郁,文章有料,加 JiuXinDev 入群志衍,Android 搬磚路上不孤單

前言

即學(xué)即用 Android Jetpack 系列Blog的目的是通過學(xué)習(xí) Android Jetpack 完成一個(gè)簡單的Demo暖庄,本文是即學(xué)即用 Android Jetpack 系列Blog的第七篇。

由于 Android Jetpack 在前一時(shí)間里更新了新的庫 Startup楼肪、Hit 和 Page 3培廓,那么《即學(xué)即用Android Jetpack》系列文章就需要加入新的內(nèi)容了。

在接下來的幾周里春叫,除了增加新的 Android Jetpack 文章以外肩钠,我還會(huì)對之前的入門 Android Jetpack 中的項(xiàng)目 【Hoo】 中所使用的舊的 Jetpack 庫進(jìn)行升級(jí)。

Jetpack系列文章??:

第一篇:《即學(xué)即用Android Jetpack - Navigation》
第二篇:《即學(xué)即用Android Jetpack - Data Binding》
第三篇:《即學(xué)即用Android Jetpack - ViewModel & LiveData》
第四篇:《即學(xué)即用Android Jetpack - Room》
第五篇:《即學(xué)即用Android Jetpack - Paging》
第六篇:《即學(xué)即用Android Jetpack - WorkManger》
第七篇:《即學(xué)即用Android Jetpack - Startup》
項(xiàng)目總結(jié)篇:《學(xué)習(xí)Android Jetpack? 實(shí)戰(zhàn)和教程這里全都有象缀!》

目錄

目錄

一蔬将、介紹

從庫名 StartUp 來看爷速,不難猜出央星,它是一個(gè)跟啟動(dòng)相關(guān)的庫。

我們先從背景講起惫东,一些第三方庫需要Activity啟動(dòng)之前去進(jìn)行初始化莉给,比如說我們之前談過的 WorkManager 和 常見的數(shù)據(jù)庫相關(guān)的庫,不可能說進(jìn)入到 Activity 的時(shí)候我再去初始化廉沮,因?yàn)檫@種初始化可能會(huì)比較耗時(shí)颓遏,給用戶帶來的體驗(yàn)也比較差。

我們再來談一下常用的庫初始化的方法:

  1. 自定義 Application滞时,并在 Application#onCreate() 中進(jìn)行初始化叁幢。優(yōu)點(diǎn)也是它的缺點(diǎn),需要手動(dòng)調(diào)用坪稽,但是能自己控制調(diào)用時(shí)機(jī)曼玩。
  2. 自定義 ContentProvider,并在 ContentProvider#onCreate() 中進(jìn)行初始化窒百。優(yōu)點(diǎn)是自動(dòng)調(diào)用黍判,降低開發(fā)者的學(xué)習(xí)成本,缺點(diǎn)是 ContentProvider 是一個(gè)相對來說比較重的操作篙梢,初始化一個(gè) ContentProvider 帶來的開銷比較小顷帖,如果大家開發(fā)的第三方庫都使用這種操作呢?結(jié)果可想而知,延長我們 App 的啟動(dòng)時(shí)間贬墩。

借用郭神《Jetpack新成員榴嗅,App Startup一篇就懂》里的空 ContentProvider 初始化的時(shí)候的開銷:

ContentProvider消耗

有了上面的基礎(chǔ),我們就可以講 StartUp 的使用了陶舞,StartUp 采用的是第二種方式录肯,它的目的是僅僅是為了使用一個(gè) ConttentProvider 來初始化那些需要初始化的庫。

圖片來自《AndroidX: App Startup》吊说,不使用 Startup 的時(shí)候:

多個(gè)ContentProvider

使用 Startup 的時(shí)候:

Startup的使用場景

其實(shí)我感覺真正的事實(shí)并不是這樣的论咏,而是:

真實(shí)場景

Startup 并不能解決已經(jīng)使用 ContentProvider 進(jìn)行初始化的第三方庫,而對于沒有使用 ContentProvider 初始化颁井,并且需要初始化的庫厅贪,我可以只選擇一個(gè) ContentProvider 進(jìn)行初始化,或者在 Application 中的 onCreate() 方法中進(jìn)行初始化雅宾,還可以省去引入一個(gè)庫和創(chuàng)建 ContentProvider 的開銷养涮。

不過既然谷歌創(chuàng)建了 Startup,總歸是有用處的眉抬,學(xué)習(xí)方式仍然推薦官方文檔:

官方文檔:https://developer.android.com/topic/libraries/app-startup

二贯吓、使用

Startup 的使用方式很簡單。

第一步 添加依賴

dependencies {
    implementation "androidx.startup:startup-runtime:1.0.0-alpha02"
}

第二步 實(shí)現(xiàn)Initializer

實(shí)現(xiàn) Initializer 需要實(shí)現(xiàn)其中的兩個(gè)方法蜀变,我們先以 Room 數(shù)據(jù)庫初始化為例:

class RoomInitializer : Initializer<AppDataBase> {
    override fun create(context: Context): AppDataBase {
        return AppDataBase.getInstance(context)
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        return emptyList()
    }
}

需要實(shí)現(xiàn)兩個(gè)方法:

  • onCreate:在這個(gè)方法執(zhí)行需要初始化的動(dòng)作悄谐,比如在上面的 RoomInitializer 中的 AppDataBase.getInstance(context),我會(huì)進(jìn)行數(shù)據(jù)的初始化库北,具體的代碼我就不放了爬舰。
  • dependencies:比如說我當(dāng)前庫 A 依賴庫 B,B 初始化成功以后才能進(jìn)行 A 的初始化寒瓦,這個(gè)時(shí)候我就需要返回包含 B 的 InitializerClassList情屹。

我們這里再創(chuàng)建一個(gè) PushInitializer,假設(shè)它必須再 Room 初始化完成以后它才能進(jìn)行初始化:

class PushInitializer  :Initializer<PushSdk>{
    override fun create(context: Context): PushSdk {
        val push = PushSdk("MPush")
        push.registerPush()
        return push
    }

    override fun dependencies(): List<Class<out Initializer<*>>> {
        return listOf(RoomInitializer::class.java)
    }
}

/**
 * 這是一個(gè)偽造的推送類 PushSdk
 */
data class PushSdk(val name:String){
    fun registerPush(){
        print("Hello,i'm registering push")
    }
}

是不是感覺很簡單杂腰。

這里談一下我在官方文檔遇到的一個(gè)坑垃你,我看到官方文檔上可以建 WorkManager 的 Initializer,代碼是這樣的:

// Initializes WorkManager.
class WorkManagerInitializer : Initializer<WorkManager> {
    override fun create(context: Context): WorkManager {
        val configuration = Configuration.Builder().build()
        WorkManager.initialize(context, configuration)
        return WorkManager.getInstance()
    }
    override fun dependencies(): List<Class<out Initializer<*>>> {
        // No dependencies on other libraries.
        return emptyList()
    }
}

如果你這樣寫喂很,恭喜你惜颇,接下來,你會(huì)收到一個(gè)這樣的閃退:

java.lang.RuntimeException: Unable to get provider androidx.startup.InitializationProvider: androidx.startup.StartupException: androidx.startup.StartupException: java.lang.IllegalStateException: WorkManager is already initialized.

意思是我們的 WorkManager 已經(jīng)初始化過了恤筛,不需要再初始化了官还。

因?yàn)?WorkManagerInitializer 這個(gè)類繼承了 ContentProvider,它已經(jīng)在 ContentProvider#onCreate() 方法中對 WorkManager 進(jìn)行了初始化毒坛,我們再在 Startup 進(jìn)行初始化就是多此一舉望伦。

第三步 在AndroidManifest文件中聲明InitializationProvider

畢竟 Startup 采用的是 ContentProvider 的方式進(jìn)行初始化林说,所以在 AndroidManifest 初始化是避免不了的。

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="com.joe.jetpackdemo.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <!-- This entry makes ExampleLoggerInitializer discoverable. -->
    <meta-data
        android:name="com.joe.jetpackdemo.common.start.PushInitializer"
        android:value="androidx.startup" />
</provider>

我們需要注意的是 meta-data 標(biāo)簽屯伞,需要初始化的 Initializer 都會(huì)被聲明成 meta-data腿箩,這里有一點(diǎn)可以簡化,在上面一步中劣摇,我們聲明了 PushInitializerRoomInitializer珠移,PushInitializer 是依賴于 RoomInitializer 的,被依賴的 RoomInitializer 可以不用申明末融。

第四步 使用懶加載

你可能會(huì)提出這樣的一個(gè)問題钧惧,雖然在 provider 標(biāo)簽中聲明了 Initializer,但是因?yàn)槟承┰蚬聪埃刹豢梢栽?InitializationProvider 初始化的時(shí)候不會(huì)去進(jìn)行相關(guān)庫的初始化浓瞪,而是在后面的某個(gè)時(shí)機(jī)手動(dòng)初始化?

這種懶加載的方式在 Startup 中是存在的巧婶,方法是在 meta-data 標(biāo)簽中加入 tools:node="remove"

<provider
    android:name="androidx.startup.InitializationProvider"
    android:authorities="com.joe.jetpackdemo.androidx-startup"
    android:exported="false"
    tools:node="merge">
    <!-- This entry makes ExampleLoggerInitializer discoverable. -->
    <meta-data
        android:name="com.joe.jetpackdemo.common.start.PushInitializer"
        android:value="androidx.startup"
        tools:node="remove"/>
</provider>

之后在你想進(jìn)行初始化的地方調(diào)用:

AppInitializer.getInstance(context)
    .initializeComponent(PushInitializer::class.java)

三乾颁、總結(jié)

目前看來,Stratup 的并沒有特別大的優(yōu)勢艺栈,也許是幫我們簡化了依賴邏輯英岭?

目瞪口呆

如果你有更好的見解,歡迎在下方評論留言湿右。

引用文章:

《AndroidX: App Startup》
《Jetpack新成員诅妹,App Startup一篇就懂》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市诅需,隨后出現(xiàn)的幾起案子漾唉,更是在濱河造成了極大的恐慌荧库,老刑警劉巖堰塌,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異分衫,居然都是意外死亡场刑,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蚪战,熙熙樓的掌柜王于貴愁眉苦臉地迎上來牵现,“玉大人,你說我怎么就攤上這事邀桑∠固郏” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵壁畸,是天一觀的道長贼急。 經(jīng)常有香客問我茅茂,道長,這世上最難降的妖魔是什么太抓? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任空闲,我火速辦了婚禮,結(jié)果婚禮上走敌,老公的妹妹穿的比我還像新娘碴倾。我一直安慰自己,他們只是感情好掉丽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布跌榔。 她就那樣靜靜地躺著,像睡著了一般捶障。 火紅的嫁衣襯著肌膚如雪矫户。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天残邀,我揣著相機(jī)與錄音皆辽,去河邊找鬼。 笑死芥挣,一個(gè)胖子當(dāng)著我的面吹牛驱闷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播空免,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼空另,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了蹋砚?” 一聲冷哼從身側(cè)響起扼菠,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎坝咐,沒想到半個(gè)月后循榆,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡墨坚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年秧饮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片泽篮。...
    茶點(diǎn)故事閱讀 38,809評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡盗尸,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出帽撑,到底是詐尸還是另有隱情泼各,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布亏拉,位于F島的核電站扣蜻,受9級(jí)特大地震影響寸癌,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弱贼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一蒸苇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吮旅,春花似錦溪烤、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至责嚷,卻和暖如春鸳兽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背罕拂。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工揍异, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爆班。 一個(gè)月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓衷掷,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柿菩。 傳聞我的和親對象是個(gè)殘疾皇子戚嗅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內(nèi)容

  • 通過這篇文章你將學(xué)習(xí)到以下內(nèi)容:App Startup 是什么?App Startup 為我們解決了什么問題枢舶?為什...
    灬佐手邊閱讀 557評論 0 1
  • 久違的晴天懦胞,家長會(huì)。 家長大會(huì)開好到教室時(shí)凉泄,離放學(xué)已經(jīng)沒多少時(shí)間了躏尉。班主任說已經(jīng)安排了三個(gè)家長分享經(jīng)驗(yàn)。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,515評論 16 22
  • 創(chuàng)業(yè)是很多人的夢想旧困,多少人為了理想和不甘選擇了創(chuàng)業(yè)來實(shí)現(xiàn)自我價(jià)值醇份,我就是其中一個(gè)。 創(chuàng)業(yè)后吼具,我由女人變成了超人,什...
    亦寶寶閱讀 1,804評論 4 1
  • 今天感恩節(jié)哎矩距,感謝一直在我身邊的親朋好友拗盒。感恩相遇!感恩不離不棄锥债。 中午開了第一次的黨會(huì)陡蝇,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,559評論 0 11
  • 可愛進(jìn)取痊臭,孤獨(dú)成精。努力飛翔登夫,天堂翱翔识椰。戰(zhàn)爭美好牲距,孤獨(dú)進(jìn)取。膽大飛翔,成就輝煌榜旦。努力進(jìn)取,遙望环肘,和諧家園勿璃。可愛游走...
    趙原野閱讀 2,723評論 1 1