Wdróż bibliotekę pakietu SDK Java

Platforma Androida zawiera dużą liczbę wspólnych bibliotek Javy, które można opcjonalnie uwzględnić w ścieżce klas aplikacji za pomocą tagu <uses-library> w pliku manifestu aplikacji. Aplikacje łączą się z tymi bibliotekami, więc należy je traktować jak pozostałe interfejsy API Androida pod względem zgodności, sprawdzania interfejsu API i obsługi narzędzi. Pamiętaj jednak, że większość bibliotek nie ma tych funkcji.

Typ modułu java_sdk_library ułatwia zarządzanie bibliotekami tego rodzaju. Producenci urządzeń mogą używać tego mechanizmu w przypadku własnych udostępnionych bibliotek Java, aby zachować zgodność wsteczną interfejsów API. Jeśli producenci urządzeń używają własnych wspólnych bibliotek Java za pomocą tagu <uses-library> zamiast ścieżki bootclass, java_sdk_library może zweryfikować, czy te biblioteki Java są stabilne pod względem interfejsu API.

java_sdk_library implementuje opcjonalne interfejsy API pakietu SDK na potrzeby aplikacji. Biblioteki zaimplementowane za pomocą java_sdk_library w pliku build (Android.bp) wykonują te operacje:

  • Biblioteki z zasobnikami generowane są tak, aby zawierały stubs, stubs.systemstubs.test. Te biblioteki z zasobami podrzędnymi są tworzone przez rozpoznawanie adnotacji @hide, @SystemApi@TestApi.
  • Usługa java_sdk_library zarządza plikami specyfikacji interfejsu API (np. current.txt) w podkatalogu interfejsu API. Te pliki są porównywane z najnowszym kodem, aby mieć pewność, że są to najnowsze wersje. Jeśli nie, pojawi się komunikat o błędzie z instrukcjami aktualizacji. Ręcznie sprawdź wszystkie zmiany w aktualizacji, aby mieć pewność, że spełniają Twoje oczekiwania.

    Aby zaktualizować wszystkie interfejsy API, użyj m update-api. Aby sprawdzić, czy interfejs API jest aktualny, użyj m checkapi.
  • Pliki specyfikacji interfejsu API są sprawdzane pod kątem najnowszych opublikowanych wersji Androida, aby zapewnić zgodność wsteczną interfejsu API z wcześniejszymi wersjami. Moduł java_sdk_library udostępniany w ramach AOSP umieszcza swoje wcześniejsze wersje w katalogu prebuilts/sdk/<latest number>.
  • W przypadku sprawdzania plików specyfikacji interfejsu API możesz wykonać jedną z tych 3 działań:
    • Zezwól na wykonanie kontroli. (Nic nie rób.)
    • Aby wyłączyć sprawdzanie, dodaj do pliku java_sdk_library następujące informacje:
      unsafe_ignore_missing_latest_api: true,
    • Podaj puste interfejsy API dla nowych modułów java_sdk_library, tworząc puste pliki tekstowe o nazwie module_name.txt w katalogu version/scope/api.
  • Jeśli biblioteka implementacji dla środowiska uruchomieniowego jest zainstalowana, plik XML jest generowany i instalowany.

Jak działa java_sdk_library

java_sdk_library o nazwie X tworzy:

  1. 2 kopie biblioteki implementacji: jedna biblioteka o nazwie Xi druga o nazwie X.impl. Biblioteka X jest zainstalowana na urządzeniu. Biblioteka X.impl jest dostępna tylko wtedy, gdy inne moduły potrzebują wyraźnego dostępu do biblioteki implementacji, na przykład do użytku w testach. Pamiętaj, że dostęp jawny jest potrzebny rzadko.
  2. Zakresy można włączać i wyłączać, aby dostosować dostęp. (Podobnie jak w przypadku modyfikatorów dostępu do słów kluczowych w języku Java, zakres publiczny zapewnia szeroki zakres dostępu, a zakres testowy zawiera interfejsy API używane tylko do testowania). Dla każdego włączonego zakresu biblioteka tworzy:
    • Moduł źródłowy zastępników (typu droidstubs) – korzysta ze źródła implementacji i wyprowadza zestaw źródeł zastępników wraz z plikiem specyfikacji interfejsu API.
    • Biblioteka podkładów (typu modułu java_library) to skompilowana wersja podkładów. Biblioteki używane do kompilacji nie są takie same jak te dostarczone do java_sdk_library, co zapewnia, że szczegóły implementacji nie przedostaną się do zaczepów interfejsu API.
    • Jeśli do skompilowania stubów potrzebujesz dodatkowych bibliotek, użyj właściwości stub_only_libs i stub_only_static_libs, aby je podać.

Jeśli java_sdk_library ma nazwę „X” i jest kompilowane jako „X”, zawsze odwołuj się do niego w ten sposób i nie zmieniaj go. Podczas kompilacji zostanie wybrana odpowiednia biblioteka. Aby mieć pewność, że masz najbardziej odpowiednią bibliotekę, sprawdź, czy w zawartych w niej elementach nie ma błędów. Wprowadź niezbędne poprawki, korzystając z tych wskazówek:

  • Aby sprawdzić, czy masz odpowiednią bibliotekę, otwórz wiersz poleceń i sprawdź, które szablony są tam wymienione:
    • Zakres jest zbyt szeroki: zależna biblioteka wymaga określonego zakresu interfejsów API. W bibliotece znajdziesz jednak interfejsy API wykraczające poza ten zakres, np. interfejsy API systemu zawarte w interfejsach API publicznych.
    • Zakres jest zbyt wąski: zależna biblioteka nie ma dostępu do wszystkich wymaganych bibliotek. Na przykład biblioteka zależna musi używać interfejsu API systemu, ale zamiast tego uzyskuje interfejs API publiczny. Zwykle powoduje to błąd kompilacji, ponieważ brakuje wymaganych interfejsów API.
  • Aby naprawić bibliotekę, wykonaj tylko jedną z tych czynności:
    • Zmień sdk_version, aby wybrać potrzebną wersję. LUB
    • Wyraźnie określ odpowiednią bibliotekę, np. <X>.stubs lub <X>.stubs.system.

Użycie X w java_sdk_library

Biblioteka implementacji X jest używana, gdy jest do niej odwołuje się apex.java_libs. Jednak z powodu ograniczenia Soong, gdy biblioteka X jest wywoływana z innego modułu java_sdk_library w tej samej bibliotece APEX, należy użyć X.impl wyraźnie, a nie biblioteki X.

Gdy odwołanie do java_sdk_library pochodzi z innego miejsca, używana jest biblioteka z zakładkami. Biblioteka pustych elementów jest wybierana na podstawie ustawienia właściwości sdk_version w module zależnym. Na przykład moduł, który określa sdk_version: "current", używa publicznych zaczepów, a moduł, który określa sdk_version: "system_current", używa zaczepów systemowych. Jeśli nie uda się znaleźć dopasowania ścisłego, zostanie użyta biblioteka zbliżona. java_sdk_library, który udostępnia tylko publiczny interfejs API, udostępni publiczne stuby wszystkim.

Tworzenie procesu za pomocą biblioteki Java SDK
Rysunek 1. Tworzenie procesu za pomocą biblioteki pakietu SDK Java

Przykłady i źródła

Właściwości srcsapi_packages muszą występować w elementach java_sdk_library.

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

AOSP zaleca (ale nie wymaga) wyraźnego włączenia zakresów interfejsów API, których mają używać nowe instancje java_sdk_library. Możesz też (opcjonalnie) przenieść istniejące instancje java_sdk_library, aby wyraźnie włączyć zakresy interfejsu API, których będą używać:

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

Aby skonfigurować bibliotekę impl używaną w czasie wykonywania, użyj wszystkich właściwości java_library, takich jak hostdex, compile_dexerrorprone.

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

Aby skonfigurować biblioteki z zasobnikami, użyj tych właściwości:

  • merge_annotations_dirsmerge_inclusion_annotations_dirs.
  • api_srcs: lista opcjonalnych plików źródłowych, które są częścią interfejsu API, ale nie są częścią biblioteki czasu wykonywania.
  • stubs_only_libs: lista bibliotek Javy, które znajdują się na ścieżce klas podczas kompilowania stubów.
  • hidden_api_packages: lista nazw pakietów, które muszą być ukryte przed interfejsem API.
  • droiddoc_options: dodatkowy argument dla metalava.
  • droiddoc_option_files: lista plików, do których można się odwoływać z poziomu droiddoc_options za pomocą $(location <label>), gdzie <file> to wpis na liście.
  • annotations_enabled.

Interfejs java_sdk_library jest interfejsem java_library, ale nie jest to moduł droidstubs, więc nie obsługuje wszystkich właściwości droidstubs. Poniższy przykład pochodzi z pliku 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,
    }

Zachowanie zgodności wstecznej

System kompilacji sprawdza, czy interfejsy API zachowują zgodność wsteczną, porównując najnowsze pliki interfejsu API z wygenerowanymi plikami interfejsu API w momencie kompilacji. java_sdk_library przeprowadza sprawdzanie zgodności na podstawie informacji dostarczonych przez prebuilt_apis. Wszystkie biblioteki utworzone za pomocą java_sdk_library muszą mieć pliki API w najnowszej wersji api_dirsprebuilt_apis. Po wydaniu wersji pliki list interfejsu API i biblioteki szablonów można pobrać za pomocą kompilacji dystrybucji z użyciem PRODUCT=sdk_phone_armv7-sdk.

Właściwość api_dirs to lista katalogów wersji interfejsu API w prebuilt_apis. Katalogi wersji interfejsu API muszą znajdować się na poziomie katalogu Android.bp.

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

Skonfiguruj katalogi w strukturze version/scope/api/ w katalogu prebuilts. version odpowiada poziomowi interfejsu API, a scope określa, czy katalog jest publiczny, systemowy czy testowy.

  • version/scope zawiera biblioteki Java.
  • version/scope/api zawiera pliki API .txt. Tutaj utwórz puste pliki tekstowe o nazwach 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