Java SDK-Bibliothek implementieren

Die Android-Plattform enthält eine große Anzahl freigegebener Java-Bibliotheken, die optional mit dem <uses-library>-Tag im App-Manifest in den Klassenpfad von Apps aufgenommen werden können. Apps werden mit diesen Bibliotheken verknüpft. Behandeln Sie sie daher in Bezug auf Kompatibilität, API-Überprüfung und Tool-Unterstützung wie den Rest der Android API. Die meisten Bibliotheken bieten diese Funktionen jedoch nicht.

Mit dem Modultyp java_sdk_library können Sie Bibliotheken dieser Art verwalten. Gerätehersteller können diesen Mechanismus für ihre eigenen freigegebenen Java-Bibliotheken verwenden, um die Abwärtskompatibilität ihrer APIs beizubehalten. Wenn Gerätehersteller ihre eigenen freigegebenen Java-Bibliotheken über das <uses-library>-Tag anstelle des Bootclass-Pfads verwenden, kann java_sdk_library prüfen, ob diese Java-Bibliotheken API-stabil sind.

Der java_sdk_library implementiert optionale SDK-APIs für die Verwendung in Apps. Bibliotheken, die über java_sdk_library in Ihrer Build-Datei (Android.bp) implementiert werden, führen die folgenden Vorgänge aus:

  • Die Stub-Bibliotheken werden so generiert, dass sie stubs, stubs.system und stubs.test enthalten. Diese Stub-Bibliotheken werden durch Erkennen von @hide-, @SystemApi- und @TestApi-Anmerkungen erstellt.
  • Der java_sdk_library verwaltet API-Spezifikationsdateien (z. B. current.txt) in einem API-Unterverzeichnis. Diese Dateien werden mit dem neuesten Code verglichen, um sicherzustellen, dass sie die aktuellsten Versionen sind. Andernfalls erhalten Sie eine Fehlermeldung mit einer Anleitung zum Aktualisieren. Prüfen Sie alle Änderungen an der Aktualisierung manuell, um sicherzustellen, dass sie Ihren Erwartungen entsprechen.

    Verwenden Sie m update-api, um alle APIs zu aktualisieren. Verwenden Sie m checkapi, um zu prüfen, ob eine API auf dem neuesten Stand ist.
  • Die API-Spezifikationsdateien werden anhand der neuesten veröffentlichten Android-Versionen geprüft, um sicherzustellen, dass die API abwärtskompatibel mit früheren Releases ist. Die java_sdk_library-Module, die im Rahmen von AOSP bereitgestellt werden, platzieren ihre zuvor veröffentlichten Versionen in prebuilts/sdk/<latest number>.
  • Bei den Prüfungen der API-Spezifikationsdateien haben Sie eine der folgenden drei Möglichkeiten:
    • Lassen Sie die Prüfungen zu. (Nichts tun.)
    • Deaktivieren Sie die Prüfungen, indem Sie java_sdk_library Folgendes hinzufügen:
      unsafe_ignore_missing_latest_api: true,
    • Stellen Sie leere APIs für neue java_sdk_library-Module bereit, indem Sie im Verzeichnis version/scope/api leere Textdateien mit dem Namen module_name.txt erstellen.
  • Wenn die Implementierungsbibliothek für die Laufzeit installiert ist, wird eine XML-Datei generiert und installiert.

Funktionsweise von java_sdk_library

Mit einer java_sdk_library namens X wird Folgendes erstellt:

  1. Zwei Kopien der Implementierungsbibliothek: eine Bibliothek namens X und eine andere namens X.impl. Die Bibliothek X ist auf dem Gerät installiert. Die Bibliothek X.impl ist nur vorhanden, wenn andere Module expliziten Zugriff auf die Implementierungsbibliothek benötigen, z. B. für die Verwendung bei Tests. Ein expliziter Zugriff ist selten erforderlich.
  2. Bereiche können aktiviert und deaktiviert werden, um den Zugriff anzupassen. Ähnlich wie bei den Java-Modifizierern für den Keyword-Zugriff bietet ein öffentlicher Bereich einen umfassenden Zugriff. Ein Testbereich enthält APIs, die nur für Tests verwendet werden. Für jeden aktivierten Bereich erstellt die Bibliothek Folgendes:
    • Ein Stub-Quellmodul (vom Typ droidstubs) – es nutzt die Implementierungsquelle und gibt eine Reihe von Stub-Quellen zusammen mit der API-Spezifikationsdatei aus.
    • Eine Stubs-Bibliothek (vom Typ java_library-Modul) ist die kompilierte Version der Stubs. Die zum Kompilieren verwendeten Bibliotheken sind nicht mit denen identisch, die für die java_sdk_library bereitgestellt werden. So wird verhindert, dass Implementierungsdetails in die API-Stubs gelangen.
    • Wenn Sie zusätzliche Bibliotheken zum Kompilieren der Stubs benötigen, verwenden Sie die Properties stub_only_libs und stub_only_static_libs, um sie anzugeben.

Wenn ein java_sdk_libraryX“ heißt und mit „X“ kompiliert wird, beziehen Sie sich immer darauf und ändern Sie es nicht. Für den Build wird eine geeignete Bibliothek ausgewählt. Prüfen Sie Ihre Stubs, um sicherzustellen, dass Sie die richtige Bibliothek haben, und sehen Sie nach, ob der Build Fehler verursacht hat. Nehmen Sie mithilfe dieser Anleitung die erforderlichen Korrekturen vor:

  • Prüfen Sie in der Befehlszeile, ob Sie eine geeignete Bibliothek haben, und sehen Sie sich an, welche stubs dort aufgeführt sind, um den Umfang zu bestimmen:
    • Zu großer Umfang: Die abhängige Bibliothek benötigt einen bestimmten Umfang an APIs. Sie sehen jedoch APIs in der Bibliothek, die nicht in diesen Bereich fallen, z. B. System-APIs, die in den öffentlichen APIs enthalten sind.
    • Zu enger Umfang: Die abhängige Bibliothek hat keinen Zugriff auf alle erforderlichen Bibliotheken. Beispielsweise muss die abhängige Bibliothek die System-API verwenden, erhält aber stattdessen die öffentliche API. Das führt in der Regel zu einem Kompilierungsfehler, da die erforderlichen APIs fehlen.
  • Führen Sie nur einen der folgenden Schritte aus, um die Bibliothek zu korrigieren:
    • Ändern Sie sdk_version, um die gewünschte Version auszuwählen. ODER
    • Geben Sie die entsprechende Bibliothek explizit an, z. B. <X>.stubs oder <X>.stubs.system.

java_sdk_library X usage

Die Implementierungsbibliothek X wird verwendet, wenn auf sie von apex.java_libs verwiesen wird. Aufgrund einer Soong-Einschränkung muss X.impl jedoch ausdrücklich verwendet werden, wenn auf die Bibliothek X von einem anderen java_sdk_library-Modul innerhalb derselben APEX-Bibliothek verwiesen wird.X

Wenn auf die java_sdk_library von einem anderen Ort aus verwiesen wird, wird eine Stub-Bibliothek verwendet. Die Stubs-Bibliothek wird gemäß der sdk_version-Property-Einstellung des abhängigen Moduls ausgewählt. In einem Modul, in dem sdk_version: "current" angegeben ist, werden beispielsweise die öffentlichen stubs verwendet, während in einem Modul, in dem sdk_version: "system_current" angegeben ist, die System-Stubs verwendet werden. Wenn keine genaue Übereinstimmung gefunden werden kann, wird die nächstgelegene Stub-Bibliothek verwendet. Ein java_sdk_library, das nur eine öffentliche API bereitstellt, stellt die öffentlichen stubs für alle zur Verfügung.

Ablauf mit Java SDK-Bibliothek erstellen
Abbildung 1: Build-Vorgang mit Java SDK-Bibliothek

Beispiele und Quellen

Die Properties srcs und api_packages müssen im java_sdk_library vorhanden sein.

java_sdk_library {
        name: "com.android.future.usb.accessory",
        srcs: ["src/**/*.java"],
        api_packages: ["com.android.future.usb"],
    }

AOSP empfiehlt (erfordert es aber nicht), dass bei neuen java_sdk_library-Instanzen die zu verwendenden API-Bereiche explizit aktiviert werden. Optional können Sie auch vorhandene java_sdk_library-Instanzen migrieren, um die zu verwendenden API-Bereiche explizit zu aktivieren:

java_sdk_library {
         name: "lib",
         public: {
           enabled: true,
         },
         system: {
           enabled: true,
         },
         
    }

Verwenden Sie zum Konfigurieren der für die Laufzeit verwendeten impl-Bibliothek alle normalen java_library-Properties wie hostdex, compile_dex und 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,
    }

Verwenden Sie die folgenden Eigenschaften, um Stub-Bibliotheken zu konfigurieren:

  • merge_annotations_dirs und merge_inclusion_annotations_dirs.
  • api_srcs: Die Liste der optionalen Quelldateien, die Teil der API, aber nicht Teil der Laufzeitbibliothek sind.
  • stubs_only_libs: Die Liste der Java-Bibliotheken, die sich beim Erstellen von Stubs im Klassenpfad befinden.
  • hidden_api_packages: Liste der Paketnamen, die von der API ausgeblendet werden müssen.
  • droiddoc_options: Zusätzliches Argument für metalava.
  • droiddoc_option_files: Listet die Dateien auf, auf die in droiddoc_options über $(location <label>) verwiesen werden kann, wobei <file> ein Eintrag in der Liste ist.
  • annotations_enabled.

java_sdk_library ist ein java_library, aber kein droidstubs-Modul und unterstützt daher nicht alle droidstubs-Properties. Das folgende Beispiel stammt aus der Datei android.test.mock library build.

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,
    }

Abwärtskompatibilität beibehalten

Das Build-System prüft, ob die APIs abwärtskompatibel sind, indem es die neuesten API-Dateien während der Buildzeit mit den generierten API-Dateien vergleicht. Die java_sdk_library führt die Kompatibilitätsprüfung anhand der von prebuilt_apis bereitgestellten Informationen durch. Alle mit java_sdk_library erstellten Bibliotheken müssen API-Dateien in der neuesten Version von api_dirs in prebuilt_apis haben. Wenn Sie die Version veröffentlichen, werden in der API Dateien und Stub-Bibliotheken aufgelistet, die mit dem Dist-Build mit PRODUCT=sdk_phone_armv7-sdk abgerufen werden können.

Die api_dirs-Eigenschaft ist eine Liste der API-Versionsverzeichnisse in prebuilt_apis. Die Verzeichnisse der API-Versionen müssen sich auf der Verzeichnisebene Android.bp befinden.

prebuilt_apis {
       name: "foo",
       api_dirs: [
           "1",
           "2",
             ....
           "30",
           "current",
       ],
    }

Konfigurieren Sie die Verzeichnisse mit der version/scope/api/-Struktur im Verzeichnis „prebuilts“. version entspricht der API-Ebene und scope definiert, ob das Verzeichnis öffentlich, systemisch oder ein Testverzeichnis ist.

  • version/scope Java-Bibliotheken enthält.
  • version/scope/api enthält API-.txt-Dateien. Erstellen Sie hier leere Textdateien mit den Namen module_name.txt und 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