Android 平台包含大量共用 Java 函式庫,可以選擇將這些函式庫包含在應用程式清單中帶有<uses-library>
標記的應用程式的類別路徑中。應用程式連結到這些庫,因此在相容性、API 審查和工具支援方面將它們視為 Android API 的其餘部分。但請注意,大多數函式庫沒有這些功能。
java_sdk_library
模組類型有助於管理此類庫。設備製造商可以將此機制用於自己的共享 Java 庫,以保持其 API 的向後相容性。如果裝置製造商透過<uses-library>
標記而不是引導類別路徑使用自己的共用 Java 函式庫,則java_sdk_library
可以驗證這些 Java 函式庫是否是 API 穩定的。
java_sdk_library
實作可選的 SDK API 供應用程式使用。透過建置檔案 ( Android.bp
) 中的java_sdk_library
實現的庫執行以下操作:
- 產生的存根庫包括
stubs
、stubs.system
和stubs.test
。這些存根庫是透過識別@hide
、@SystemApi
和@TestApi
註解來建立的。 -
java_sdk_library
管理 API 子目錄中的 API 規格檔(例如current.txt
)。這些文件會根據最新程式碼進行檢查,以確保它們是最新版本。如果不是,您會收到錯誤訊息,說明如何更新它們。手動檢查所有更新變更以確保它們符合您的期望。
若要更新所有 API,請使用m update-api
。若要驗證 API 是否是最新的,請使用m checkapi
。 - API 規格檔案會根據最新發布的 Android 版本進行檢查,以確保 API 向後相容於早期版本。作為 AOSP 的一部分提供的
java_sdk_library
模組將其先前發布的版本放在prebuilts/sdk/<latest number>
中。 - 對於 API 規格文件檢查,您可以執行以下三個操作之一:
- 允許檢查繼續進行。 (什麼都不要做。)
- 透過將以下內容新增至
java_sdk_library
來停用檢查:
unsafe_ignore_missing_latest_api: true,
- 透過在
version/scope/api
目錄中建立名為module_name.txt
的空白文字文件,為新的java_sdk_library
模組提供空 API。 - 如果安裝了運行時的實作庫,則會產生並安裝 XML 檔案。
java_sdk_library 的工作原理
名為X
的java_sdk_library
建立以下內容:
- 實作庫的兩個副本:一個名為
X
函式庫,另一個名為X.impl
。庫X
安裝在設備上。只有當其他模組需要明確存取實作庫(例如用於測試時)時,庫X.impl
才存在。請注意,很少需要明確訪問。 - 可以啟用和停用範圍來自訂存取。 (與 Java 關鍵字存取修飾符類似,公共作用域提供廣泛的存取權限;測試作用域包含僅在測試中使用的 API。)對於每個啟用的作用域,該程式庫會建立以下內容:
- 存根模組(
droidstubs
模組類型)- 使用實作來源並輸出一組存根以及 API 規格文件。 - 存根庫(
java_library
模組類型) - 是存根的編譯版本。用於編譯它的函式庫與提供給java_sdk_library
的函式庫不同,這確保了實作細節不會洩漏到 API 存根中。 - 如果您需要其他函式庫來編譯存根,請使用
stub_only_libs
和stub_only_static_libs
屬性來提供它們。
如果java_sdk_library
被稱為“ X
”,並且正在編譯為“ X
”,請始終以這種方式引用它並且不要修改它。建置將選擇合適的庫。為了確保您擁有最合適的程式庫,請檢查您的存根以查看建置是否引入了錯誤。使用本指南進行必要的更正:
- 透過查看命令列並檢查其中列出的存根來確定您的範圍,驗證您是否擁有合適的庫:
- 範圍太廣:依賴函式庫需要一定範圍的 API。但是您會看到庫中包含的 API 超出了該範圍,例如公共 API 中包含的系統 API。
- 範圍太窄:依賴函式庫無法存取所有必要的函式庫。例如,依賴函式庫需要使用系統 API,但改為取得公共 API。這通常會導致編譯錯誤,因為缺少所需的 API。
- 要修復庫,只需執行以下操作之一:
- 更改
sdk_version
選擇您需要的版本。或者 - 明確指定適當的庫,例如
<X>.stubs
或<X>.stubs.system
。
java_sdk_library X 用法
當從apex.java_libs
引用實作庫X
時,就會使用它。但是,由於 Soong 的限制,當從同一 APEX 庫中的另一個java_sdk_library
模組引用庫X
時,必須明確使用X.impl
,而不是庫X
。
當從其他地方引用java_sdk_library
時,將使用存根庫。根據依賴模組的sdk_version
屬性設定選擇存根庫。例如,指定sdk_version: "current"
的模組使用公共存根,而指定sdk_version: "system_current"
的模組使用系統存根。如果找不到精確匹配,則使用最接近的存根庫。僅提供公共 API 的java_sdk_library
將為每個人提供公共存根。
範例和來源
srcs
和api_packages
屬性必須存在於java_sdk_library
中。
java_sdk_library { name: "com.android.future.usb.accessory", srcs: ["src/**/*.java"], api_packages: ["com.android.future.usb"], }
AOSP 建議(但不要求)新的java_sdk_library
實例明確啟用它們想要使用的 API 範圍。您也可以(可選)遷移現有java_sdk_library
實例以明確啟用它們將使用的 API 範圍:
java_sdk_library { name: "lib", public: { enabled: true, }, system: { enabled: true, }, … }
若要設定用於執行時間的impl
函式庫,請使用所有常規java_library
屬性,例如hostdex
、 compile_dex
和errorprone
。
java_sdk_library { name: "android.test.base", srcs: ["src/**/*.java"], errorprone: { javacflags: ["-Xep:DepAnn:ERROR"], }, hostdex: true, api_packages: [ "android.test", "android.test.suitebuilder.annotation", "com.android.internal.util", "junit.framework", ], compile_dex: true, }
若要配置存根庫,請使用下列屬性:
-
merge_annotations_dirs
和merge_inclusion_annotations_dirs
。 -
api_srcs
:屬於 API 的一部分但不屬於執行時間庫的可選來源檔案清單。 -
stubs_only_libs
:建構存根時位於類別路徑中的 Java 函式庫的清單。 -
hidden_api_packages
:必須對 API 隱藏的套件名稱清單。 -
droiddoc_options
: metalava的附加參數。 -
droiddoc_option_files
:列出可以使用$(location <label>)
從droiddoc_options
中引用的文件,其中<file>
是清單中的條目。 -
annotations_enabled
。
java_sdk_library
是一個java_library
,但它不是droidstubs
模組,因此不支援所有droidstubs
屬性。以下範例取自android.test.mock 函式庫建置檔。
java_sdk_library { name: "android.test.mock", srcs: [":android-test-mock-sources"], api_srcs: [ // Note: The following aren’t APIs of this library. Only APIs under the // android.test.mock package are taken. These do provide private APIs // to which android.test.mock APIs reference. These classes are present // in source code form to access necessary comments that disappear when // the classes are compiled into a Jar library. ":framework-core-sources-for-test-mock", ":framework_native_aidl", ], libs: [ "framework", "framework-annotations-lib", "app-compat-annotations", "Unsupportedappusage", ], api_packages: [ "android.test.mock", ], permitted_packages: [ "android.test.mock", ], compile_dex: true, default_to_stubs: true, }
保持向後相容性
建置系統透過將最新的 API 檔案與建置時產生的 API 檔案進行比較來檢查 API 是否保持了向後相容性。 java_sdk_library
使用prebuilt_apis
提供的資訊執行相容性檢查。所有使用java_sdk_library
建構的函式庫都必須在prebuilt_apis
的最新版本api_dirs
中具有 API 檔案。當您發布版本時,可以使用 dist build 並使用PRODUCT=sdk_phone_armv7-sdk
來取得 API 列出檔案和存根庫。
api_dirs
屬性是prebuilt_apis
中 API 版本目錄的清單。 API 版本目錄必須位於Android.bp
目錄層級。
prebuilt_apis { name: "foo", api_dirs: [ "1", "2", .... "30", "current", ], }
配置 prebuilts 目錄下的version / scope /api/
結構的目錄。 version
對應 API 級別, scope
定義目錄是公共目錄、系統目錄還是測試目錄。
-
version / scope
包含 Java 函式庫。 -
version / scope /api
包含 API.txt
檔案。在此建立名為module_name .txt
和module_name -removed.txt
的空白文字檔案。├── 30 │ ├── public │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ ├── system │ │ ├── api │ │ │ ├── android.test.mock-removed.txt │ │ │ └── android.test.mock.txt │ │ └── android.test.mock.jar │ └── test │ ├── api │ │ ├── android.test.mock-removed.txt │ │ └── android.test.mock.txt │ └── android.test.mock.jar └── Android.bp