原文:https://medium.com/androiddevelopers/migrating-to-androidx-tip-tricks-and-guidance-88d5de238876
Jetpack是一組可以幫助你更容易寫(xiě)出高質(zhì)量apps的庫(kù),工具和引導(dǎo)。Jetpack通過(guò)最佳實(shí)踐,限制樣板代碼,并簡(jiǎn)化負(fù)責(zé)的任務(wù),讓編碼變得更容易。讓你專(zhuān)注于你的業(yè)務(wù)代碼。
AndroidX是Jetpack中所有的庫(kù)的軟件包名稱(chēng)??梢詫ndroidX視為用于開(kāi)發(fā),測(cè)試,版本化和發(fā)布JetPack庫(kù)的開(kāi)源項(xiàng)目。
在I/O 2018上,我們就宣布將support庫(kù)重構(gòu)為AndroidX命名空間,目前重構(gòu)工作已經(jīng)通過(guò)Support Library 28的完結(jié)和AndroidX 1.0的發(fā)布完成。
為什么要做這樣的遷移?
現(xiàn)在已經(jīng)是時(shí)候遷移從Android Support Library 到AndroidX上。這里有以下四點(diǎn)原因:
- Android Support Library已經(jīng)完成了它的任務(wù)了。28.0是Android Support命名空間的最后一個(gè)發(fā)布版本了,同時(shí)Android Support 這個(gè)命名空間在不久只會(huì)將不在進(jìn)行維護(hù)。所以,如果你想你在Support Library中的bug得到修復(fù)或者使用新的功能,你就需要遷移到AndroidX上。
- 更好的包管理。使用AndroidX,可以讓你得到標(biāo)準(zhǔn)化和獨(dú)立的版本控制,以及更標(biāo)準(zhǔn)化的命名和更頻繁的發(fā)布。
- 很多庫(kù)已經(jīng)遷移到了AndroidX上了,比如Google Play Services,F(xiàn)irebase,Butterknife,Mockito 2和SQLDelight等。
- 所有新發(fā)布的Jetpack庫(kù)都將使用AndroidX命名空間,所以如果你想使用例如Jetpack Compose或者CameraX這樣到新功能,你就需要遷移到AndroidX上。
遷移準(zhǔn)備
在你遷移你到代碼到AndroidX上之前,你需要做這些事情:
- 備份你到項(xiàng)目,如果你有使用版本管理工具,你只需要將你到代碼提交備份就好,因?yàn)檫w移可能會(huì)修改你項(xiàng)目中到不少文件,如果你不想丟失你到代碼的話(huà)。
- 你可以創(chuàng)建一個(gè)新的分支去進(jìn)行遷移工作,等遷移完成后再進(jìn)行分支合并。
- 如果可以的話(huà),在你的遷移過(guò)程中,盡量暫停功能的開(kāi)發(fā)或者最小化的開(kāi)發(fā)(至少不要在遷移過(guò)程中進(jìn)行重構(gòu)或者引入新的功能),這樣能減少你代碼合并時(shí)可能發(fā)生的合并沖突。
開(kāi)始遷移
在遷移過(guò)程中,重點(diǎn)在于解決發(fā)生的錯(cuò)誤,使你的項(xiàng)目能編譯通過(guò)并且通過(guò)所有測(cè)試。
Step 1:更新所有的Support Library版本到28
我們不推薦你直接從舊版本的Support Library(比如26或27)遷移到AndroidX,因?yàn)檫@樣你不僅面對(duì)命名空間修改的問(wèn)題,你還有可能面臨因?yàn)樾聨?kù)與舊庫(kù)API改變導(dǎo)致的錯(cuò)誤問(wèn)題。
所以,我推薦你先將Support Library 更新到28,解決了所有API更改到問(wèn)題,確保你到項(xiàng)目能在28版本的Support Library下編譯通過(guò)并通過(guò)所有測(cè)試。
Support Library28和AndroidX 1.0是等效的二進(jìn)制文件,意思是兩者只是包命名空間的不同:所有的APIs都是一樣的。這就意味著,你從Support Library28遷移到AndroidX,你幾乎不需要修改什么。
Step 2:啟用Jetifier
Jetifier用來(lái)幫助遷移你引用的第三方依賴(lài)庫(kù)使用AndroidX。Jetifier將會(huì)改變這些第三方依賴(lài)庫(kù)的字節(jié)碼,讓它們能與使用AndroidX的項(xiàng)目兼容。
在項(xiàng)目中啟用Jetifier,只需要將下面的代碼添加到你的gradle.properties文件中即可:
android.useAndroidX=true
android.enableJetifier=true
現(xiàn)在,當(dāng)代碼自動(dòng)導(dǎo)入庫(kù)的時(shí)候,將會(huì)導(dǎo)入該庫(kù)到AndroidX版本,而不是舊到Support Library。
Step 3.更新dependencies(依賴(lài))
在開(kāi)始遷移之前,你應(yīng)該將你引用的第三方庫(kù)更新到該庫(kù)到最新版本,否則可能會(huì)導(dǎo)致編譯不通過(guò)。
如果你使用的是會(huì)自動(dòng)生成代碼的庫(kù),Jetifier將不會(huì)對(duì)其進(jìn)行修改。因此,你需要檢查你的代碼生成庫(kù)是否與AndroidX兼容。
如果你想要直接跳過(guò)步驟2和步驟3,則可能會(huì)遇到一些錯(cuò)誤:
- 如果你使用的第三方庫(kù)的代碼與AndroidX不兼容。在這種情況下,跟下面堆棧類(lèi)似的堆棧跟蹤將想你說(shuō)明,它正在嘗試獲取舊版本的Support Library:
…
Error : Program type already present: android.support.v4.app.INotificationSideChannel$Stub$Proxy |
Reason: Program type already present: android.support.v4.app.INotificationSideChannel$Stub$Proxy
…
- 如果你的項(xiàng)目只進(jìn)行了部分的遷移,則可能會(huì)遇到重復(fù)類(lèi)的錯(cuò)誤,因?yàn)樗噲D從Support Library和AndroidX中提取相同的代碼。堆棧跟蹤將可能顯示以下內(nèi)容:
…
Duplicate class android.support.v4.app.INotificationSideChannel found in modules classes.jar (androidx.core:core:1.0.0) and classes.jar (com.android.support:support-compat:28.0.0)
…
Step 4:更新你的源碼
你有三個(gè)方案可以來(lái)更新你的源碼來(lái)使用AndroidX:
- Android Studio
- 手動(dòng)更新
- Bash腳本
如果你使用的Android Studio版本是3.2以上的。你可以通過(guò)使用Refactor功能菜單里的Migrate to AndroidX選項(xiàng)去更新你的代碼。這是最推薦你的方案,因?yàn)锳ndroid Studio 可以在重構(gòu)時(shí)檢查你的源碼并做出正確的決定。
image.png
如果你不是使用Android Studio開(kāi)發(fā)或者你的項(xiàng)目結(jié)構(gòu)太復(fù)雜導(dǎo)致使用Migrate to AndroidX選項(xiàng)無(wú)法涵蓋。則可以利用類(lèi)映射csv文件來(lái)實(shí)現(xiàn)查找和替換bash腳本進(jìn)行替換。這個(gè)腳本應(yīng)該做到能找到有android.support類(lèi)的所有源碼實(shí)例,然后將它們替換稱(chēng)同等功能的AndroidX。
具體來(lái)說(shuō),就是腳本要使用類(lèi)映射的CSV文件用grep命令和sed命令來(lái)替換程序包名。但是,這是一種非常暴力的遷移方法,這種方法可能無(wú)法充分和正確的找到和替換所有代碼。
除此之外,更新也可以通過(guò)純手動(dòng)的方式一點(diǎn)點(diǎn)解決。
如果你決定使用手動(dòng)更新的方法,你可以訪(fǎng)問(wèn)遷移到AndroidX頁(yè)面,你可以在這里找到詳細(xì)關(guān)于Support Library和AndroidX對(duì)應(yīng)的映射關(guān)系。
你也可以將這個(gè)CSV文件下載下來(lái)。
到這里,你應(yīng)該就可以讓你的項(xiàng)目可以使用AndroidX并能編譯通過(guò)。
那些令人討厭的意外
盡管我們?cè)谶@里討論的工具和流程應(yīng)該能引導(dǎo)大多數(shù)項(xiàng)目進(jìn)行順利的遷移,但是我們發(fā)現(xiàn)在某些情況下,你可能需要手動(dòng)進(jìn)行修改。
版本配置文件
你需要手動(dòng)重新定義庫(kù)版本的變量。這里說(shuō)明以下,在遷移之前,你的build.gradle文件可能是這樣的:
ext.versions = [
‘drawer’ : ‘28.0.0’,
‘rview’ : ‘28.0.0’
]
implementation “com.android.support:drawerlayout:${versions.drawer}”
implementation “com.android.support:recyclerview-v7:${versions.rview}”
在使用遷移工具完成遷移只會(huì),你的代碼可能變成這個(gè)樣子:
ext.versions = [
‘drawer’ : ‘28.0.0’,
‘rview’ : ‘28.0.0’
]
implementation “androidx.drawerlayout:drawerlayout:1.0.0”
implementation “androidx.recyclerview:recyclerview:1.0.0”
你看DrawerLayout和RecyclerView使用的是AndroidX的包,但是版本號(hào)并沒(méi)有使用到版本號(hào)變量,所以,你需要對(duì)其進(jìn)行手動(dòng)修改:
ext.versions = [
‘drawer’ : ‘1.0.0’,
‘rview’ : ‘1.0.0’
]
implementation “androidx.drawerlayout:drawerlayout:${versions.drawer}”
implementation “androidx.recyclerview:recyclerview:${versions.rview}”
混淆配置和構(gòu)建腳本
遷移工具并不會(huì)自動(dòng)更新我們的混淆文件和任何相關(guān)的內(nèi)置腳本。因此,如果你有使用到這些文件,并且里面包含來(lái)Support Library包名稱(chēng),你需要手動(dòng)進(jìn)行修改。
獲取最新的穩(wěn)定版本
遷移工具提取最新版本的AndroidX庫(kù)。結(jié)果可能導(dǎo)致你使用到的某些庫(kù)是Alpha版本,比如遷移之前,Support Library可能是:
implementation ‘com.android.support:appcompat-v7:28.0.0’
遷移之后,你可能使用的是Android對(duì)應(yīng)的alpha版本的庫(kù):
implementation ‘a(chǎn)ndroidx.appcompat:appcompat:1.1.0-alpha01’
所以,如果你希望使用穩(wěn)定版本的庫(kù),你需要手動(dòng)去更新以下版本:
implementation ‘a(chǎn)ndroidx.appcompat:appcompat:1.0.2’
更多幫助和資源
你可以在遷移到AndroidX這個(gè)界面找到相關(guān)的教程,工具和可能遇到問(wèn)題等更多信息。這個(gè)頁(yè)面包含了AndroidX項(xiàng)目的概述,遷移指南,舊的Support Library庫(kù)和新的穩(wěn)定版或者alpha版的AndroidX的映射表以及你編寫(xiě)遷移腳本需要到的CSV文件。
在這里也有一篇文章詳細(xì)介紹了在Plaid示例項(xiàng)目中向AndroidX的遷移
最后,這里有一個(gè)問(wèn)題跟蹤器,你可以在其中可以看到Android團(tuán)隊(duì)正在處理的遷移工具的問(wèn)題。當(dāng)然你也可以使用頁(yè)面左上方的按鈕告訴我們?cè)谶w移工具中發(fā)現(xiàn)的任何問(wèn)題。
最后的思考
如果你還沒(méi)升級(jí)到AndroidX,那么現(xiàn)在就是一個(gè)不錯(cuò)的時(shí)機(jī),你可以利用Jetpack庫(kù)來(lái)為你的項(xiàng)目簡(jiǎn)化開(kāi)發(fā)復(fù)雜度。通過(guò)本文的引導(dǎo),你會(huì)發(fā)現(xiàn)在大多數(shù)情況下,遷移是一件很簡(jiǎn)單的事情。
