實現 Java SDK 庫

Android平台包含大量可任選地包括在應用程序的與類路徑共享Java庫<uses-library>標籤在應用清單。應用程序鏈接到這些庫,因此在兼容性、API 審查和工具支持方面,將它們與 Android API 的其餘部分一樣對待。但是請注意,大多數庫都沒有這些功能。

java_sdk_library模塊類型有助於管理這類庫。設備製造商可以將此機制用於他們自己的共享 Java 庫,以保持其 API 的向後兼容性。如果設備製造商通過使用他們自己的共享Java庫<uses-library>標籤,而不是bootclass路徑, java_sdk_library可以驗證這些Java庫API穩定。

java_sdk_library工具可選SDK的API由應用程序使用。圖書館通過實施java_sdk_library請在生成文件( Android.bp )執行以下操作:

  • 生成存根庫包括stubsstubs.system ,和stubs.test 。這些存根庫通過識別創建@hide@SystemApi@TestApi註解。
  • 所述java_sdk_library管理API規格的文件(如current.txt在API子目錄)。這些文件會根據最新代碼進行檢查,以確保它們是最新版本。如果不是,您會收到一條錯誤消息,說明如何更新它們。手動檢查所有更新更改以確保它們符合您的期望。
  • API 規範文件根據最近發布的 Android 版本進行檢查,以確保 API 向後兼容早期版本。所述java_sdk_library作為AOSP地方的一部分而提供的模塊的先前發布的版本在prebuilts/sdk/<latest number>
  • 關於API規範文件的檢查,你可以做以下三件事之一
    • 允許檢查繼續進行。 (不要做任何事情。)
    • 禁用檢查中加入以下到java_sdk_library
      unsafe_ignore_missing_latest_api: true,
    • 提供了新的空的API java_sdk_library通過創建名為空文本文件的模塊module_name.txtversion/scope/api目錄
  • 如果安裝了運行時的實現庫,則會生成並安裝一個 XML 文件。

java_sdk_library 如何工作

一個java_sdk_library稱為X創建如下:

  1. 實現庫的兩個副本:一個庫名為X和另一個名為X.impl 。庫X上安裝的設備。圖書館X.impl有只有被其他模塊,如用於測試使用需要實現庫明確的訪問。請注意,很少需要顯式訪問。
  2. 可以啟用和禁用範圍以自定義訪問。 (類似於 Java 關鍵字訪問修飾符,公共範圍提供廣泛的訪問範圍;測試範圍包含僅用於測試的 API。)對於每個啟用的範圍,庫創建以下內容:
    • 甲存根源模塊(的droidstubs模塊類型) -消耗的執行源極和與所述API規範文件一起輸出一組的存根源。
    • 甲存根(庫java_library模塊類型) -是短截線的編譯版本。用於編譯這個庫是不一樣提供給那些java_sdk_library ,這確保了實現細節不漏到API存根。
    • 如果你需要額外的庫編譯存根,使用stub_only_libsstub_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 用法

實現庫X ,當它從引用被使用apex.java_libs 。然而,由於一個宋限制,當庫X由另一個引用java_sdk_library相同APEX庫內模塊, X.impl明確地必須使用,不庫X

java_sdk_library是從其他地方引用,使用存根庫。該樁模塊庫是根據根據模塊的選擇sdk_version屬性設置。例如,一個模塊,它指定sdk_version: "current"使用公共存根,而指定一個模塊sdk_version: "system_current"使用系統存根。如果無法找到精確匹配,則使用最近的存根庫。一個java_sdk_library只提供一個公共的API將提供公共存根給大家。

使用 Java SDK 庫構建流程
圖1.使用Java SDK庫構建流程

示例和來源

srcsapi_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屬性,如hostdexcompile_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_dirsmerge_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_libraryjava_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必須有最新版本的API文件api_dirsprebuilt_apis 。當您鬆開的版本,API列表中的文件和存根庫可以用蒸餾水構建以獲得PRODUCT=sdk_phone_armv7-sdk

api_dirs屬性是API版本的目錄列表prebuilt_apis 。該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 .txtmodule_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