針對程式庫作者進行最佳化

作為程式庫作者,您應確保應用程式開發人員能輕鬆將程式庫整合至應用程式,同時維持高品質的使用者體驗。您應確保程式庫與 Android 最佳化相容,無須額外設定,或記錄程式庫可能不適合在 Android 上使用。

本文件的目標對象為已發布的程式庫開發人員,但也可能對大型模組化應用程式中內部程式庫模組的開發人員有所助益。

如果您是應用程式開發人員,並想瞭解如何最佳化 Android 應用程式,請參閱「啟用應用程式最佳化功能」。如要瞭解哪些程式庫適合使用,請參閱「明智選擇程式庫」。

使用 codegen 而非反射

盡可能使用程式碼產生 (codegen) 而非反射。程式碼產生和反射都是在程式設計時避免使用樣板程式碼的常見方法,但程式碼產生功能與 R8 等應用程式最佳化工具的相容性較高:

  • 使用 codegen 時,系統會在建構程序期間分析及修改程式碼。由於在編譯時間後不會有任何重大修改,最佳化工具就會知道最終需要哪些程式碼,以及哪些程式碼可以安全移除。
  • 透過反射,您可以在執行階段分析及操作程式碼。由於程式碼必須執行後才能真正完成,最佳化工具就無法得知哪些程式碼可安全移除。這可能會在執行階段透過反射移除動態使用的程式碼,導致使用者遇到應用程式當機問題。

許多現代程式庫都使用 codegen 而非反射。如需常見的進入點,請參閱 KSP,這項功能會用於 RoomDagger2 等許多其他項目。

反光效果是否適當

如果您必須使用反射功能,請只將反射功能用於下列任一項目:

  • 特定指定類型 (特定介面實作者或子類別)
  • 使用特定執行階段註解的程式碼

以這種方式使用反射功能可限制執行階段成本,並可編寫指定消費者保留規則

這種特定且有目標的反射形式是您在 Android 架構 (例如在加載活動、檢視畫面和可繪項目時) 和 AndroidX 程式庫 (例如在建構 WorkManager ListenableWorker 或 RoomDatabase) 中都會看到的模式。相反地,Gson 的開放式反射功能不適合用於 Android 應用程式

編寫用戶保留規則

程式庫應封裝「消費者」保留規則,這些規則的格式與應用程式保留規則相同。這些規則會整合至程式庫構件 (AAR 或 JAR),並在使用程式庫時,於 Android 應用程式最佳化期間自動使用。

AAR 程式庫

如要為 AAR 程式庫新增消費者規則,請在 Android 程式庫模組的建構指令碼中使用 consumerProguardFiles 選項。詳情請參閱建立程式庫模組的指南

Kotlin

android {
    defaultConfig {
        consumerProguardFiles("consumer-proguard-rules.pro")
    }
    ...
}

Groovy

android {
    defaultConfig {
        consumerProguardFiles 'consumer-proguard-rules.pro'
    }
    ...
}

JAR 程式庫

如要將規則與以 JAR 形式提供的 Kotlin/Java 程式庫捆綁,請將規則檔案放入最終 JAR 的 META-INF/proguard/ 目錄,並加上任何檔案名稱。舉例來說,如果程式碼位於 <libraryroot>/src/main/kotlin,請將消費者規則檔案放在 <libraryroot>/src/main/resources/META-INF/proguard/consumer-proguard-rules.pro,規則就會在輸出 JAR 的正確位置中捆綁。

確認最終 JAR 套件規則正確無誤,方法是檢查規則是否位於 META-INF/proguard 目錄中。

支援不同的縮減工具 (進階)

您可以根據特定縮減器 (R8 或 ProGuard) 和特定縮減器版本,調整規則。這樣一來,程式庫就能在使用新壓縮器版本的專案中正常運作,同時允許在使用舊版壓縮器的專案中繼續使用現有規則。

如要指定目標縮減規則,您必須在 AAR 或 JAR 程式庫的特定位置加入這些規則,如下所述。

In an AAR library:
    consumer-proguard-rules.pro (legacy location)
    classes.jar
    └── META-INF
        └── com.android.tools (targeted shrink rules location)
            ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
            └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

In a JAR library:
    META-INF
    ├── proguard/<ProGuard-rules-file> (legacy location)
    └── com.android.tools (targeted shrink rules location)
        ├── r8-from-<X>-upto-<Y>/<R8-rules-file>
        └── proguard-from-<X>-upto-<Y>/<ProGuard-rules-file>

這表示指定的縮減規則會儲存在 JAR 的 META-INF/com.android.tools 目錄中,或是 AAR 的 classes.jarMETA-INF/com.android.tools 目錄中。

在該目錄下,可以有多個目錄,其名稱採用 r8-from-<X>-upto-<Y>proguard-from-<X>-upto-<Y> 的格式,用來指出目錄內的規則是為哪個版本的縮減器編寫。請注意,-from-<X> 和 -upto-<Y> 部分為選用,<Y> 版本為排他性,且版本範圍必須連續。

舉例來說,r8-upto-8.0.0, r8-from-8.0.0-upto-8.2.0r8-from-8.2.0 可組成有效的指定縮減規則組合。R8 會使用 r8-from-8.0.0-upto-8.2.0 目錄下的規則,從 8.0.0 版到 8.2.0 版 (不包括 8.2.0 版)。

有了這些資訊,Android Gradle 外掛程式就能從相符的 R8 目錄中選取規則。如果程式庫未指定指定的縮減規則,Android Gradle 外掛程式會從舊版位置 (AAR 為 proguard.txt,JAR 為 META-INF/proguard/<ProGuard-rules-file>) 選取規則。