我的GitHub | 我的博客 | 我的微信 | 我的郵箱 |
---|---|---|---|
baiqiantao | baiqiantao | bqt20094 | baiqiantao@sina.com |
AndroidX
Google 2018 IO 大會推出了擴展庫 AndroidX,AndroidX 是對 android.support.xxx
包的整理后產物。由於之前的support包過於混亂,所以,google推出了 androidX 用於替換support包。
其只是將原來的android.*
替換成androidx.*
,只有包名和Maven工件名受到影響,原來的類名、方法名和字段名不會更改。
由於在后續版本中,會逐步放棄對 support 的升級和維護,所以,我們必須盡快遷移到 androidX。
Jetpack components are part of the AndroidX library. Learn more about components on the Jetpack home page.
AndroidX 的變化
常用依賴庫對比
詳細變化內容,可以下載CSV格式映射文件:androidx-class-mapping.csv
Old build artifact | AndroidX build artifact |
---|---|
com.android.support:appcompat-v7:28.0.2 |
androidx.appcompat:appcompat:1.0.0 |
com.android.support:design:28.0.2 |
com.google.android.material:material:1.0.0 |
com.android.support:support-v4:28.0.2 |
androidx.legacy:legacy-support-v4:1.0.0 |
com.android.support:recyclerview-v7:28.0.2 |
androidx.recyclerview:recyclerview:1.0.0 |
com.android.support.constraint:constraint-layout:1.1.2 |
androidx.constraintlayout:constraintlayout:1.1.2 |
常用支持庫類對比
詳細變化內容,可以下載CSV格式映射文件:androidx-artifact-mapping.csv
Support Library class | AndroidX class |
---|---|
android.support.v4.app.Fragment |
androidx.fragment.app.Fragment |
android.support.v4.app.FragmentActivity |
androidx.fragment.app.FragmentActivity |
android.support.v7.app.AppCompatActivity |
androidx.appcompat.app.AppCompatActivity |
android.support.v7.app.ActionBar |
androidx.appcompat.app.ActionBar |
android.support.v7.widget.RecyclerView |
androidx.recyclerview.widget.RecyclerView |
官方文檔介紹
AndroidX is the open-source project that the Android team uses to develop, test, package, version and release libraries within Jetpack.
AndroidX是Android團隊用於在Jetpack中開發,測試,打包,發布和發布庫的開源項目。
AndroidX is a major improvement to the original Android Support Library. Like the Support Library, AndroidX ships separately from the Android OS and provides backwards-compatibility
across Android releases. AndroidX fully replaces the Support Library by providing feature parity and new libraries. In addition AndroidX includes the following features:
AndroidX是對原始Android支持庫的重大改進。與支持庫一樣,AndroidX與Android操作系統分開提供,並提供跨Android版本的向后兼容性。 AndroidX通過提供功能奇偶校驗和新庫完全取代了支持庫。此外,AndroidX還包括以下功能:
- All packages in AndroidX live in a consistent namespace starting with the string
androidx
. The Support Library packages have been mapped into correspondingandroidx.*
packages. For a full mapping of all the old classes and build artifacts to the new ones, see the Package Refactoring page.
AndroidX中的所有軟件包都以字符串androidx開頭,位於一致的命名空間中。支持庫包已映射到相應的androidx。*包。有關所有舊類和構建工件的完整映射到新構件,請參閱“包重構”頁面。
- Unlike the Support Library, AndroidX packages are separately maintained and updated. The
androidx
packages use strict Semantic Versioning starting with version 1.0.0. You can update AndroidX libraries in your project independently.
與支持庫不同,AndroidX軟件包是單獨維護和更新的。 androidx軟件包使用嚴格的語義版本控制,從版本1.0.0開始。您可以單獨更新項目中的AndroidX庫。
- All new Support Library development will occur in the AndroidX library. This includes maintenance of the original Support Library artifacts and introduction of new Jetpack components.
所有新的支持庫開發都將在AndroidX庫中進行。這包括維護原始支持庫工件和引入新的Jetpack組件。
If you want to use AndroidX in a new project, you need to set the compile SDK to Android 9.0 (API level 28) or higher and set both of the following Android Gradle plugin flags to true
in your gradle.properties
file.
android.useAndroidX
: When set totrue
, the Android plugin uses the appropriate AndroidX library instead of a Support Library. The flag isfalse
by default if it is not specified.android.enableJetifier
: When set totrue
, the Android plugin automatically migrates existing third-party libraries to use AndroidX by rewriting their binaries. The flag isfalse
by default if it is not specified.
遷移到 AndroidX
1、修改 gradle.properties
android.useAndroidX=true
android.enableJetifier=true
其中:
android.useAndroidX=true
表示當前項目啟用 androidxandroid.enableJetifier=true
表示將依賴包
也遷移到androidx。如果取值為false,表示不遷移依賴包到androidx,但在使用依賴包中的內容時可能會出現問題,當然了,如果你的項目中沒有使用任何三方依賴,那么,此項可以設置為false
2、將AS更新至 AS 3.2 及以上
將 Gradle 插件版本改為 4.6 及以上
將 compileSdkVersion、buildToolsVersion 版本改為 28.0.2及以上
3、在AndroidStudio 3.2 或更高版本中執行如下操作:
Refactor > Migrate to AndroidX
如果你的項目 compileSdkVersion 低於28,點擊Migrate to AndroidX...會提示:
You need to have at least have compileSdk 28 set in your module
build.gradle
to refactor to androidx
在執行該操作時會提醒我們是否將當前項目打包備份。如果你提前已經做好了備份,可以忽略;如果沒有備份,則先備份。
后續問題處理
參考文章
Android Support 庫和 AndroidX 沖突問題
手動修改錯誤包名
由於 Migrate to AndroidX
執行之后,部分控件的包名/路徑名轉換的有問題,所以還需要我們手動調整(包括修改xml布局文件和.java/.kt文件)。
如:ViewPager、RecyclerView 等,這些內容在遷移完成之后,包名是 androidx.core.weight.xxxx
,這是一個錯誤的包名,我們必須手動修改,否則,無法正常編譯。點擊綠色 Run(運行) 按鈕時會詳細報出哪里有錯誤。
注意,在 AndroidStudio 的 build 選項卡中一次最多只會報 50條錯誤!所以,可能在你修完第一批之后,后面還有N個50。此處要保持一個平靜的 💗。
修復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文件中搜索這個控件名,然后刪除重復即可。
去除 attr.xml 中重復的屬性名稱
在遷移到 androidX 之前,我們為自定義控件編寫自定義屬性時,可以與android已有的屬性重名,但是,在AndroidX環境下不行了,如果存在重名的情況, 必然會報錯——會提示你重復定義。
錯誤示例
<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/mode,需要手動改成其他。
Glide中的注解不兼容androidX
遷移到 androidX 之后,Glide中使用的 android.support.annotation.CheckResult
和 android.support.annotation.NonNull
這兩個注解無法遷移。之前有用戶在Glide中提過issue: 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
//這兩行是為了解決 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"
規范包名
這里所說的包名,指的是項目中的文件夾名稱。在之前版本中,我們命名包名時可能會出現大寫字母,雖然這並不符合Java命名規范,但起碼能正常編譯和運行。然而,升級到 AndroidStudio3.2 + androidX 環境后,必須嚴格遵守命名規范,否則,可能報錯,從而導致不能正常編譯和運行。
對於包名的命名規范,好像要求並非十分嚴格。因為我發現,部分包含大寫字母的報名在編譯時會報錯,部分不報錯。但是,遵守規范總會更好一點!
修改未自動遷移的三方庫
雖然我們從gradle中配置了遷移三方庫的參數,但是,由於三方庫的版本更新問題,也可能會遷移失敗。在三方庫遷移失敗時,如果使用了數據綁定,通常會報如下錯誤:
碰到上述錯誤之后,我們可以按下列步驟處理:
- 在gradle文件中,將可升級的三方庫升級(通常情況下,可升級的三方庫會有黃色提示)
- 如果gradle中可升級的庫都升級之后依舊報上述錯誤,那么,可以新建一個項目,然后將gradle中的依賴庫逐個拷貝到新項目中,沒拷貝一個編譯一次,這樣可以確認是哪個三方庫有問題。(實際操作時可以使用二分法的方式進行,每次拷貝一半的依賴庫,然后編譯)。然后就可以有針對性的處理了
莫名問題的解決
遷移過程中如果爆出一些 android 包本身或者其他莫名其妙的問題時,先去 xml 布局文件 或 .java
文件中找一下,是否有繼續引用 xxx.support.xxx
的情況,如果有,記得替換成 androidx.xxx.xxx
包下的對應控件。( xxx 泛指任意內容)
2019-4-15