[譯] Plaid 應用遷移到 AndroidX 的實踐經歷

Mirosalva發表於2019-04-16

一份 AndroidX 的遷移指南

[譯] Plaid 應用遷移到 AndroidX 的實踐經歷

Virginia Poltrack 提供圖片。

Plaid 是一款呈現 Material Design 風格和豐富互動介面的有趣應用。最近這款應用通過現今的 Android 應用開發技術實現了一番重構。獲取更多應用資訊和重新設計的視覺效果,可以查閱 Restitching Plaid

和大多數 Android 應用一樣,Plaid 依賴 Android Support Library,該庫可以為新 Android 特性提供向後相容性,以便可以執行在舊版作業系統的 Android 機上。在 2018 年的 9 月份,最新的 Support Library 版本(28.0.0)被髮布,和 Support Library 一起釋出的 Android 庫已經被遷移到 AndroidX(除了 Design 庫被遷移到 Android 的 Material Components),並且這些庫的新增開發都是基於 AndroidX。因此,接收 bug 修復、新功能和其他庫更新的唯一選擇就需要將 Plaid 遷移到 AndroidX。

什麼是 AndroidX?

在 2018 Google I/O 大會上,Android 團隊釋出了 AndroidX。它是 Android 團隊用於開發、測試、打包、定版以及在 Jetpack 中釋出庫時所用到的開原始碼。和 Support Library 類似,每一個 AndroidX 庫都是獨立於 Android OS 來發布,並且提供了跨 Android 版本的向後相容性。它是對 Support Library 的重大改進和全面替代方案。

閱讀下文來了解我們如何為遷移過程準備自己的程式碼,以及執行遷移過程。

遷移前準備

我強烈建議在一個版本可控的分支做遷移工作。這樣你可以逐步解決可能出現的任何遷移問題,同時分離出每個變更用於分析定位問題。你可以在這個 Pull Request 下檢視我們的討論過程,並且通過點選下面的提交連結來跟進最新資訊。另外 Android Studio 提供了一個遷移前做工程備份的可選服務。

和任何大規模程式碼的重構工作一樣,最好在遷移到 AndroidX 期間,遷移分支與主要開發分支之間做到最少合併來避免合併衝突。雖然對其他應用來說不可行,但是我們團隊能夠臨時暫停向主分支提交程式碼以幫助遷移。一次性遷移整個應用也非常必要,因為部分遷移——同時使用 AndroidX 和 Support 庫將會導致遷移過程中的失敗。

最後,請閱讀 developer.android.com 網站上遷移至 AndroidX 文中的提示。現在讓我們開始吧!

依賴標識

在你開始之前,對程式碼準備的最重要的一點建議是:

確保你正在使用的依賴庫是與 AndroidX 相容的。

依賴於一箇舊版 support 庫的第三方庫可能與 AndroidX 不相容,這很有可能導致你的應用在遷移到 AndroidX 後無法編譯。檢查你的應用任意依賴是否相容的一個方法是訪問這些依賴的專案站點。一個更直接的方法是開始遷移,並且檢查可能出現的報錯。

對於 Plaid 應用,我們使用了一個與AndroidX 不相容的圖形載入庫 Glide 的舊版本(4.7.1)。這導致遷移後出現一個讓應用無法構建的程式碼生成問題(這是一個記錄在 Glide 工程下的類似問題),在開始遷移之前我們把 Glide 更新到版本 4.8.0(參考這次提交),這個版本新增了對 AndroidX 註解的支援。

關於這一點,請儘可能地更新到你的應用所依賴第三方庫的最新版本。這對 Support 庫而言尤其是一個好主意,因為升級到 28.0.0(截至撰寫本文的最終版本)將使遷移更加順暢。

使用 Android Studio 進行重構

遷移過程中我們使用了 Android Studio 3.2.1 版本中內建的重構工具。 AndroidX 遷移工具位於選單欄的 Refactor > Migrate to AndroidX 選項。這個選項將遷移整個專案的所有模組。

[譯] Plaid 應用遷移到 AndroidX 的實踐經歷

執行 AndroidX 重構工具後的預覽視窗。

如果你不使用 Android Studio 或者更傾向於其他工具來做遷移,請參考 ArtifactClass 來對比新舊支援庫間架構和類的改動,這些材料也有提供 CSV 格式。

Android Studio 中的 AndroidX 遷移工具是 AndroidX 遷移的主要方式。這個工具正在持續的優化中,所以如果你遇到問題或者希望檢視某個功能,請在 Google 問題追蹤頁提交一票

遷移應用

變更最少的程式碼以保證應用可以仍能正常執行。

在執行 AndroidX 遷移工具後,大量的程式碼被變更,然而專案卻無法編譯成功。此時,我們僅僅做了最少量的工作來使應用重新執行起來。

這個方法有利於把流程拆解為可控的步驟。我們留下了一些任務,諸如修復匯入順序、提取依賴變數、減少完整 classpath 的使用,以便後續的清理工作。

剛開始出現的報錯之一是重複的類 —— 像這種情況,PathSegment

Execution failed for task ':app:transformDexArchiveWithExternalLibsDexMergerForDebug'.

> com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:

如何解決這個問題參考這裡: https://developer.android.com/studio/build/dependencies#duplicate_classes.

Program type already present: androidx.core.graphics.PathSegment
複製程式碼

這是一個由遷移工具生成錯誤依賴(androidx.core:core-ktx:0.3)導致的報錯。我們手動更新(參考這次提交)到正確的依賴版本(androidx.core:core-ktx:1.0.0)。這個bug 已經在 Android Studio 3.3 Canary 9 及之後的版本被修復。我們指出這點是因為你或許在遷移過程中會遇到類似的問題。

接下來,Palette API 在新版中變得可以為空,為了暫時避開(參考這次提交)這點,我們新增了!!非空斷言操作符)。

然後我們遇到了一個 plusAssign 缺失的報錯。這個載入在 1.0.0 版本中被移除。plusAssign 的使用被臨時註釋掉了(參考這次提交)。本文的後面我們會研究對 PaletteplusAssign 問題的可持續解決方案。

現在應用可以執行了,到清理程式碼的時候了!

清理程式碼

應用在執行中,但是我們的持續整合系統報告了程式碼提交後的構建錯誤:

Execution failed for task ':designernews:checkDebugAndroidTestClasspath'.

> Conflict with dependency 'androidx.arch.core:core-runtime' in project ':designernews'. 

Resolved versions for runtime classpath (2.0.0) and compile classpath (2.0.1-alpha01) differ. This can lead to runtime crashes. 

To resolve this issue follow advice at https://developer.android.com/studio/build/gradle-tips#configure-project-wide-properties.

Alternatively, you can try to fix the problem by adding this snippet to /.../plaid/designernews/build.gradle:

  dependencies {
    implementation("androidx.arch.core:core-runtime:2.0.1-alpha01")
  }
複製程式碼

我們依照測試日誌中的參考建議,新增了缺失的依賴模組(參考這次提交)。

我們也藉此機會更新了我們的 Gradle 外掛版本、Gradle wrapper 版本、Kotlin 版本(參考這次提交)。Android Studio 推薦我們安裝 28.0.3 版本的構建工具,我們也照做了。在使用 Gradle 3.3.0-alpha13 版本外掛時我們遇到的問題,通過降級到 3.3.0-alpha8 版本的方式得到解決。

遷移工具的一個缺點是:如果你在依賴版本項使用了變數,遷移工具把它們自動內聯。我們從 build.gradle 檔案中重新提取了這些版本(參考這次提交)。

上文中我們提到了執行 AndroidX 遷移工具後對 plusAssignPalette 問題的臨時解決方案。我們通過將 AndroidX 版本降低來重新新增了 plusAssign 函式和相關測試(參考這次提交),並且恢復了被註釋了的程式碼。與此同時,我們把 Palette 引數更新到可以為空的這個版本(參考這次提交),這樣就無需使用操作符 !!

同樣的,自動轉化可能使得某些類需要使用它們的完整類路徑。做最少的手工修正是一個好的思路。作為清理工作的一部分,我們移除了完整類路徑,並在必要時重新新增了相關引用。

最後,一些少量測試相關的修改被加入工程,圍繞著測試過程中的依賴衝突(參考這次提交)和 Room 的測試用例(參考這次提交)。這時我們的工程完成全部轉化,並且我們的測試都已通過。

結束過程

儘管遇到了一些障礙,AndroidX 的遷移進展得比較順利。遇到的問題主要涉及依賴庫或類的錯誤轉換,以及新庫中的 API 變化。 幸運的是這些都相對容易解決。Plaid 現在已經準備好再被用起來了!

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章