- 190822 補充:升級 gradle 到 3.4.2 之后,禁止項目默認啟用 androidx
- 190817 補充:補充 Glide 兼容 androidx 注解的內容
- 190726 補充:細節補充
- 190325 補充:莫名問題的解決
- 181106 補充:修改未遷移成功的三方庫
1、AndroidX 簡介
點擊查看 Android 文檔中對 AndroidX 的簡介
按照官方文檔說明 AndroidX 是對 android.support.xxx 包的整理后產物。由於之前的 support 包過於混亂,所以,Google 推出了AndroidX。
由於在后續版本中,會逐步放棄對 support 的升級和維護,所以,我們必須遷移到 AndroidX .對此,官方描述如下:
Existing packages, such as the Android Support Library, are being refactored into AndroidX. Although Support Library versions 27 and lower are still available on Google Maven, all new development will be included in only AndroidX versions 1.0.0 and higher.
2、遷移步驟
2.1 修改當前項目的 gradle.properties
android.useAndroidX=true
android.enableJetifier=true
其中:
android.useAndroidX=true
表示當前項目啟用 AndroidXandroid.enableJetifier=true
表示將依賴包也遷移到AndroidX 。如果取值為 false ,表示不遷移依賴包到AndroidX,但在使用依賴包中的內容時可能會出現問題,當然了,如果你的項目中沒有使用任何三方依賴,那么,此項可以設置為 false
注意:是當前項目的 gradle.properties
, 當我們切換 AS 視圖到 Android 目錄結構時,該文件會顯示為 gradle.properties (Project Properties)
。一定要注意與 gradle.properties (Global Properties)
區分
2.2 如何遷移
在 AndroidStudio 3.2 或更高版本(截圖中 AndroidStudio 為 3.2 版本)中執行如下操作:
-
Refactor > Migrate to AndroidX
image
在執行該操作時會提醒我們是否將當前項目打包備份。如果你提前已經做好了備份,可以忽略;如果沒有備份,則先備份。
3 遷移后續
3.1 手動修改錯誤包名
由於 Migrate to AndroidX
執行之后,部分控件的包名/路徑名轉換的有問題,所以還需要我們手動調整(包括修改 xml 布局文件和 .java 或 .kt 文件)。
如:ViewPager, RecyclerView 等,這些內容在遷移完成之后,包名是 androidx.core.weight.xxxx
,這是一個錯誤的包名,我們必須手動修改,否則,無法正常編譯——點擊綠色 Run(運行) 按鈕時會詳細報出哪里有錯誤。(遷移到 androidX 之后,各包名可參考 支持庫類映射 進行修改
此處需要注意,在 AndroidStudio 的 build 選項卡中一次最多只會報 50條錯誤!! 所以,可能在你修完第一批之后,后面還有N個50。此處要保持一個平靜的💗。
3.2 修復 DataBinding 中的錯誤(重名id錯誤)
在 AndroidStudio3.2 + AndroidX 環境下,對錯誤的檢查和處理更為嚴格。如果同一個 xml 布局文件中存在同名 id ,在之前的版本中,我們可以正常編譯和運行,但是,在新的環境下, 必然會報錯,錯誤信息如下:

在上圖的錯誤信息中,我們以 DecibelBinding 為例,簡述修復過程。
-
如上圖,
無法將xxxBinding 構造器中的xxxBinding應用到指定類型
指明了出錯的 Binding類 為 DecibelBinding -
按照 DataBinding 類名的生成規則,我們可以知道,DecibelBinding 對應的 xml 文件名應該是 decibel.xml (如果你在 xml 中通過
class="xxxBinding"
指定了 DataBinding 的生成類名,那么就全局搜索吧) -
在確定了 xml 之后,我們還需要知道到底哪里出了錯誤,那么,就繼續看圖中的
錯誤:找不到符號 符號:變量 xxx
.這個變量就是控件的 id 名稱。 -
DataBinding 轉換控件 id 名的規則是:去除下划線連接符,然后將原下划線后面的第一個字母大寫。所以,圖中的 fragmentDiscoverGridItemRelativeLayout1 對應的控件id應該是:
@+id/fragment_discover_grid_item_relative_layout
, 后面之所以有一個 1 ,是因為重復了。然后,我們在對應的 xml 文件中搜索這個控件名,然后刪除重復即可。
3.3 去除 attr.xml 中重復的屬性名稱
在遷移到 AndroidX 之前,我們為自定義控件編寫自定義屬性時,可以與 android 已有的屬性重名,但是,在 AndroidX 環境下不行了,如果存在重名的情況, 必然會報錯——會提示你重復定義(詳細錯誤信息沒截圖,但翻譯過來就是重復定義了attr/xxx)。
- 錯誤示例:
<declare-styleable name="RoundImageView"> ... <!-在遷移到androidx之前,這樣寫雖然不規范,但是能用,不報錯-> <attr name="textSize" format="Integer" /> ... </declare-styleable>
- 正確示例
<declare-styleable name="RoundImageView"> ... <!-遷移到androidX之后,必須使用android:xxx 屬性,不能定義android已有的屬性-> <attr name="android:textSize" /> ... </declare-styleable>
關於重名屬性,在 AndroidX 中不知道哪個控件中包含了一個 mode 屬性,所以,如果之前你的自定義控件中有
<attr name="mode" format="xx取值類型" />
,需要手動改成其他。或者通過<attr name="android:xx屬性" />
的方式直接引用 android 中已經定義好的屬性——當然了,前提是他們的取值類型一致。
3.4 Glide 中的注解不兼容AndroidX
遷移到 AndroidX 之后,Glide 中使用的 android.support.annotation.CheckResult
和 android.support.annotation.NonNull
這兩個注解無法遷移。之前有用戶在 Glide 中提過 issue: https://github.com/bumptech/glide/issues/3185
在上述 issue 中有用戶表示,將 Glide 升級到 4.8.0 之后,可以正常遷移。但是,我這邊並不行。然后,我先升級了Glide ,又在 gralde 文件中增加了 support.annotation ,這樣才能正常編譯通過。貌似在后續 Glide 5.x 版本中會完成對 AndroidX 的完全兼容。
我的臨時解決方案:
//圖片加載——Glide implementation "com.github.bumptech.glide:glide:4.8.0 annotationProcessor "com.github.bumptech.glide:compiler:4.8.0 //CnPeng 2018/9/26 下午8:38 這兩行是為了解決 https://github.com/bumptech/glide/issues/3185 ——Glide 中的注解還沒有完全兼容androidx implementation "com.android.support:support-annotations:28.0.0-alpha3" annotationProcessor "com.android.support:support-annotations:28.0.0-alpha3"
補充: 190817 升級到 Glide 4.9.0 之后,可以正常使用 androidx 注解
具體如下:
// androidx 版本: 'androidx.appcompat:appcompat:1.0.2' // AndroidStudio 版本:3.4.2 // Gradle 插件版本:'com.android.tools.build:gradle:3.4.2' //圖片加載——Glide implementation "com.github.bumptech.glide:glide:4.9.0" implementation "com.github.bumptech.glide:okhttp3-integration:4.9.0" annotationProcessor "com.github.bumptech.glide:compiler:4.9.0" implementation 'androidx.annotation:annotation:1.1.0' annotationProcessor 'androidx.annotation:annotation:1.1.0'
3.5 規范包名(即文件夾名)
這里所說的包名,指的是項目中的文件夾名稱。在之前版本中,我們命名包名時可能會出現大寫字母,但起碼能正常編譯和運行。然而,升級到 AndroidStudio3.2 + AndroidX 環境后,可能會報錯,從而導致不能正常編譯和運行。
錯誤示例:

正確示例:

對於包的命名,好像要求並非十分嚴格。因為我發現,部分包含大寫字母的報名在編譯時會報錯,部分不報錯。(命名規則應該可以參考 res 目錄中的命名規則)
3.6 修改未自動遷移的三方庫
20181108補充:
雖然我們從 gradle 中配置了遷移三方庫的參數,但是,由於三方庫的版本更新問題,也可能會遷移失敗。在三方庫遷移失敗時,如果使用了數據綁定,通常會報如下錯誤:

碰到上述錯誤之后,我們可以按下列步驟處理:
- 1、在 gradle 文件中,將可升級的三方庫升級(通常情況下,可升級的三方庫會有黃色提示)
- 2、如果 gradle 中可升級的庫都升級之后依舊報上述錯誤,那么,可以新建一個項目,然后將 gradle 中的依賴庫逐個拷貝到新項目中,每拷貝一個編譯一次,這樣可以確認是哪個三方庫有問題。(實際操作時可以使用二分法的方式進行,每次拷貝一半的依賴庫,然后編譯)。然后就可以有針對性的處理了
3.7 莫名問題的解決
20190325 補充:
遷移過程中如果爆出一些 android 包本身或者其他莫名其妙的問題時,先去 xml 布局文件 或 .java
文件中找一下,是否有繼續引用 xxx.support.xxx
的情況,如果有,記得替換成 androidx.xxx.xxx
包下的對應控件。( xxx 泛指任意內容)
在 遷移到 AndroidX
中可以查閱 support 中的組件 在 AndrodiX 的對應內容
3.8 修復項目默認啟用 androidx 的情況(20190822補充)
當前 AS 版本:3.5.0
- 問題現象:
本地有項目已經遷移到 androidx .
然后運行其他未遷移到 androidx 的項目時,如果該項目的 gradle插件 不低於 3.4.2 ,AS 編譯時會報錯 can't resolve android.support.xx
, 當我們打開某個引用了 support 內容的類文件時,自動導包時會提示我們導入 androidx 中對應的類。
- 解決方案:
切換項目到 Android 目錄視圖,然后找到 gralde.properties ( Global Properties )
文件,強制 注釋掉 其中的 android.enableJetifier=true
和 android.useAndroidX=true
(這個全局的 gradle.properties
文件中的 androidx 配置我也忘記是自己手誤添加的還是 AS 默認啟用的了,反正干掉它就妥妥的了。)
示意圖如下:
