Implementierung der Java SDK-Bibliothek

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

Der Modultyp java_sdk_library hilft bei der Verwaltung solcher Bibliotheken. Gerätehersteller können diesen Mechanismus für ihre eigenen gemeinsam genutzten Java-Bibliotheken nutzen, um die Abwärtskompatibilität ihrer APIs aufrechtzuerhalten. Wenn Gerätehersteller ihre eigenen gemeinsam genutzten Java-Bibliotheken über das Tag <uses-library> anstelle des Bootclass-Pfads verwenden, kann java_sdk_library überprüfen, ob diese Java-Bibliotheken API-stabil sind.

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

  • Die Stubs-Bibliotheken werden so generiert, dass sie stubs , stubs.system und stubs.test enthalten. Diese Stubs-Bibliotheken werden durch die Erkennung der Annotationen @hide , @SystemApi und @TestApi erstellt.
  • Die java_sdk_library verwaltet API-Spezifikationsdateien (z. B. current.txt ) in einem API-Unterverzeichnis. Diese Dateien werden anhand des neuesten Codes überprüft, um sicherzustellen, dass es sich um die aktuellsten Versionen handelt. Ist dies nicht der Fall, erhalten Sie eine Fehlermeldung, die erklärt, wie Sie sie aktualisieren. Überprüfen Sie alle Update-Änderungen manuell, um sicherzustellen, dass sie Ihren Erwartungen entsprechen.

    Um alle APIs zu aktualisieren, verwenden Sie m update-api . Um zu überprüfen, ob eine API aktuell ist, verwenden Sie m checkapi .
  • Die API-Spezifikationsdateien werden mit den zuletzt veröffentlichten Android-Versionen verglichen, um sicherzustellen, dass die API mit früheren Versionen abwärtskompatibel ist. Die als Teil von AOSP bereitgestellten java_sdk_library Module platzieren ihre zuvor veröffentlichten Versionen in prebuilts/sdk/<latest number> .
  • Im Hinblick auf die Überprüfung der API-Spezifikationsdateien können Sie einen der folgenden drei Schritte ausführen:
    • Warten Sie, bis die Prüfungen fortgesetzt werden. (Tu nichts.)
    • Deaktivieren Sie Prüfungen, indem Sie Folgendes zu java_sdk_library hinzufügen:
      unsafe_ignore_missing_latest_api: true,
    • Stellen Sie leere APIs für neue java_sdk_library Module bereit, indem Sie leere Textdateien mit dem Namen module_name.txt im Verzeichnis version/scope/api erstellen.
  • Wenn die Implementierungsbibliothek für die Laufzeit installiert ist, wird eine XML-Datei generiert und installiert.

So funktioniert java_sdk_library

Eine java_sdk_library namens X erstellt Folgendes:

  1. Zwei Kopien der Implementierungsbibliothek: eine Bibliothek namens X und eine andere namens X.impl . 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, beispielsweise zur Verwendung beim Testen. Beachten Sie, dass ein expliziter Zugriff selten erforderlich ist.
  2. Bereiche können aktiviert und deaktiviert werden, um den Zugriff anzupassen. (Ähnlich wie Java-Schlüsselwortzugriffsmodifikatoren bietet ein öffentlicher Bereich einen breiten Zugriffsbereich; ein Testbereich enthält APIs, die nur beim Testen verwendet werden.) Für jeden aktivierten Bereich erstellt die Bibliothek Folgendes:
    • Ein Stubs-Quellmodul (vom Modultyp droidstubs “) – verbraucht die Implementierungsquelle und gibt eine Reihe von Stub-Quellen zusammen mit der API-Spezifikationsdatei aus.
    • Eine Stubs-Bibliothek (vom Modultyp java_library ) – ist die kompilierte Version der Stubs. Die zum Kompilieren verwendeten Bibliotheken sind nicht dieselben wie die für die java_sdk_library bereitgestellten Bibliotheken, wodurch sichergestellt wird, dass die Implementierungsdetails nicht in die API-Stubs gelangen.
    • Wenn Sie zum Kompilieren der Stubs zusätzliche Bibliotheken benötigen, verwenden Sie die Eigenschaften stub_only_libs und stub_only_static_libs , um diese bereitzustellen.

Wenn eine java_sdk_libraryX “ heißt und als „ X “ kompiliert wird, beziehen Sie sich immer auf diese Weise und ändern Sie sie nicht. Der Build wählt eine geeignete Bibliothek aus. Um sicherzustellen, dass Sie über die am besten geeignete Bibliothek verfügen, überprüfen Sie Ihre Stubs, um festzustellen, ob beim Build Fehler aufgetreten sind. Nehmen Sie alle erforderlichen Korrekturen anhand dieser Anleitung vor:

  • Stellen Sie sicher, dass Sie über eine geeignete Bibliothek verfügen, indem Sie in der Befehlszeile nachsehen, welche Stubs dort aufgelistet sind, um Ihren Umfang zu bestimmen:
    • Der Umfang ist zu groß: Die abhängige Bibliothek benötigt einen bestimmten Umfang an APIs. Sie sehen jedoch in der Bibliothek enthaltene APIs, die außerhalb dieses Bereichs liegen, z. B. System-APIs, die in den öffentlichen APIs enthalten sind.
    • Der Umfang ist zu eng: 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. Dies führt normalerweise zu einem Kompilierungsfehler, da benötigte APIs fehlen.
  • Um die Bibliothek zu reparieren, führen Sie nur einen der folgenden Schritte aus:
    • Ändern Sie sdk_version , um die benötigte Version auszuwählen. ODER
    • Geben Sie explizit die entsprechende Bibliothek an, z. B. <X>.stubs oder <X>.stubs.system .

java_sdk_library X-Nutzung

Die Implementierungsbibliothek X wird verwendet, wenn von apex.java_libs aus auf sie verwiesen wird. Aufgrund einer Soong-Einschränkung muss X.impl X verwendet werden java_sdk_library wenn auf X

Wenn von anderer Stelle auf die java_sdk_library verwiesen wird, wird eine Stubs-Bibliothek verwendet. Die Stubs-Bibliothek wird entsprechend der Einstellung der sdk_version Eigenschaft des jeweiligen Moduls ausgewählt. Beispielsweise verwendet ein Modul, das sdk_version: "current" angibt, die öffentlichen Stubs, während ein Modul, das sdk_version: "system_current" angibt, die System-Stubs verwendet. Wenn keine genaue Übereinstimmung gefunden werden kann, wird die nächstgelegene Stub-Bibliothek verwendet. Eine java_sdk_library , die nur eine öffentliche API bereitstellt, stellt die öffentlichen Stubs für alle bereit.

Build-Flow mit der Java SDK-Bibliothek
Abbildung 1. Build-Ablauf mit der Java SDK-Bibliothek

Beispiele und Quellen

Die Eigenschaften srcs und api_packages müssen in der 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 jedoch nicht), dass neue java_sdk_library Instanzen die API-Bereiche, die sie verwenden möchten, explizit aktivieren. Sie können (optional) auch vorhandene java_sdk_library Instanzen migrieren, um die von ihnen verwendeten API-Bereiche explizit zu aktivieren:

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

Um die zur Laufzeit verwendete impl Bibliothek zu konfigurieren, verwenden Sie alle normalen java_library Eigenschaften, wie z. B. 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 zum Konfigurieren von Stubs-Bibliotheken die folgenden Eigenschaften:

  • merge_annotations_dirs und merge_inclusion_annotations_dirs .
  • api_srcs : Die Liste optionaler 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 : Die Liste der Paketnamen, die vor 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 mithilfe von $(location <label>) verwiesen werden kann, wobei <file> ein Eintrag in der Liste ist.
  • annotations_enabled .

Die java_sdk_library ist eine java_library , aber kein droidstubs Modul und unterstützt daher nicht alle droidstubs Eigenschaften. Das folgende Beispiel wurde der Build-Datei der Bibliothek android.test.mock entnommen.

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

Wahrung der Abwärtskompatibilität

Das Build-System prüft, ob die APIs die Abwärtskompatibilität beibehalten haben, indem es die neuesten API-Dateien mit den generierten API-Dateien zum Build-Zeitpunkt 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 über API-Dateien in der neuesten Version von api_dirs in prebuilt_apis verfügen. Wenn Sie die Version veröffentlichen, listet die API Dateien auf und Stubs-Bibliotheken können mit dist build mit PRODUCT=sdk_phone_armv7-sdk abgerufen werden.

Die Eigenschaft api_dirs ist eine Liste der API-Versionsverzeichnisse in prebuilt_apis . Die API-Versionsverzeichnisse 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 Struktur version / scope /api/ im Verzeichnis „prebuilts“. version entspricht der API-Ebene und scope definiert, ob das Verzeichnis öffentlich, System oder Test ist.

  • version / scope enthält Java-Bibliotheken.
  • 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