修正最佳化問題

由於 R8 的最佳化功能會更新應用程式的程式碼,因此請務必嚴格測試應用程式的行為,確保應用程式正常運作。如果發生非預期行為,請參閱本頁指南,排解最佳化後可能發生的問題。如要進一步瞭解可用於排解最佳化問題的規則,請參閱「使用規則排解最佳化問題」。

疑難排解時,請著重於下列情況:

  • 過度最佳化導致應用程式當機:R8 最佳化過多程式碼,導致應用程式當機。
  • 最佳化不清楚或不足:R8 未能按照預期最佳化應用程式,或您需要進一步說明最佳化。

應用程式當機

如果應用程式在透過 R8 最佳化後當機,通常是因為反射中斷。如要找出不完整的反射,請遵循下列準則:

  • 您會觀察到例外狀況,表示系統透過反射機制使用指定的類別、方法或欄位。這些例外狀況通常是下列其中一項:ClassNotFoundException、NoSuchMethodException、NoSuchFieldException、NoClassDefFoundError、NoSuchMethodError、NoSuchFieldError。
  • 您會看到使用 import kotlin.reflect.* 或 import java.lang.reflect.* 參照反射的程式碼。
  • 您會發現類別建構函式的使用方式如下: Something::class.constructors。
  • 畫面會顯示 Class.forName(...)。

解決方法:新增保留規則。

如果您的程式碼會執行反射,您可以使用 Jetpack Keep 註解為該程式碼加上註解,而不必新增保留規則。Jetpack Keep Lint 檢查也會標記未註解的其他反射呼叫,協助您避免類似的當機問題。

最佳化不清楚或不充分

由於規則是從應用程式和內含程式庫套用,您可能需要進一步瞭解套用的規則,或是需要說明 R8 為何保留您預期會最佳化的特定程式碼區段。

  • 套用規則不明確:由於納入的程式庫規則也適用於應用程式,且這些程式庫的全域選項也會傳播至應用程式,因此您可能不確定套用了哪些規則。

    解決方法:查看 R8 建構專案時套用的所有規則報表,確認套用的規則。這份報表位於 ./app/build/outputs/mapping/configuration.txt。這份報告包含用於設定 R8 的所有程式庫和模組中,合併後的所有規則,可用於找出效率不彰的規則。

  • 保留過多程式碼:R8 最佳化可能會保留您預期移除的程式碼。

    解決方案:使用 -whyareyoukeeping 設定選項,瞭解程式碼保留的原因。輸出內容包含從保留程式碼到應用程式其中一個進入點的路徑。詳情請參閱 -whyareyoukeeping。

  • 難以理解原始堆疊追蹤:R8 會以各種方式變更程式碼,導致堆疊追蹤不再參照原始程式碼。例如,行號以及類別和方法的名稱可能會變更。

    解決方案:從 Android Studio Otter 3 功能推送和 AGP 9.0 開始,Logcat 會自動取消混淆處理堆疊追蹤。不過,如果您使用舊版 Android Studio,則需要手動復原原始堆疊追蹤記錄。如要復原原始堆疊追蹤,請使用 retrace 指令列工具,此工具包含在指令列工具套件之中。

    如要使用 retrace,請在指令中提供對應檔案和堆疊追蹤檔案的路徑。對應檔名為 mapping.txt,會自動與 Android App Bundle (AAB) 組合。詳情請參閱 retrace 說明文件,以及 Play 管理中心說明中心文章「如何針對當機堆疊追蹤去模糊化」。使用 Play 和 Firebase Crashlytics 時,請將 mapping.txt 檔案與服務從應用程式使用者收集到的當機資料搭配使用。下列指令說明如何從專案根目錄執行 retrace:

    $ANDROID_HOME/cmdline-tools/latest/bin/retrace app/build/outputs/mapping/$releaseVariant/mapping.txt trace.txt
    

回報錯誤

如果無法解決 R8 相關問題,請回報錯誤。