Android 平台包含大量共享 Java 库,这些库可以选择性地包含在应用的类路径中,方法是在应用清单中使用 <uses-library>
标记。应用会链接到这些库,因此在兼容性、API 审核和工具支持方面,应将其视为 Android API 的其余部分。但请注意,大多数库都不具备这些功能。
java_sdk_library
模块类型有助于管理此类库。设备制造商可以将此机制用于自己的共享 Java 库,以保持其 API 的向后兼容性。如果设备制造商通过 <uses-library>
标记而不是 bootclass 路径使用自己的共享 Java 库,则 java_sdk_library
可以验证这些 Java 库的 API 是否稳定。
java_sdk_library
实现供应用使用的可选 SDK API。java_sdk_library
在您的构建文件 (Android.bp
) 中实现的库执行以下操作:
- 生成的桩程序库包含
stubs
、stubs.system
和stubs.test
。这些桩程序库是通过识别@hide
、@SystemApi
和@TestApi
注解创建的。 java_sdk_library
管理 API 规范文件(例如current.txt
),这些文件位于 API 子目录中。系统会对照最新代码检查这些文件,以确保它们是最新的版本。如果不是,您将收到一条错误消息,其中说明了如何更新它们。手动审核所有更新更改,以确保它们符合您的预期。
要更新所有 API,请使用m update-api
。要验证 API 是否为最新版本,请使用m checkapi
。- 系统会对照最近发布的 Android 版本检查 API 规范文件,以确保 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
:列出可以从droiddoc_options
中使用$(location <label>)
引用的文件,其中<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 文件。当您发布版本时,可以使用 PRODUCT=sdk_phone_armv7-sdk
的 dist 构建获取 API 列表文件和桩程序库。
api_dirs
属性是 prebuilt_apis
中 API 版本目录的列表。API 版本目录必须位于 Android.bp
目录级别。
prebuilt_apis { name: "foo", api_dirs: [ "1", "2", .... "30", "current", ], }
使用 version/scope/api/
结构在 prebuilts 目录下配置目录。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