Mengimplementasikan library Java SDK

Platform Android berisi sejumlah besar library Java bersama yang secara opsional dapat disertakan dalam classpath aplikasi dengan tag <uses-library> dalam manifes aplikasi. Aplikasi ditautkan ke library ini, jadi perlakukan library ini seperti API Android lainnya dalam hal kompatibilitas, peninjauan API, dan dukungan alat. Namun, perlu diperhatikan bahwa sebagian besar library tidak memiliki fitur ini.

Jenis modul java_sdk_library membantu mengelola library jenis ini. Produsen perangkat dapat menggunakan mekanisme ini untuk library Java bersama mereka sendiri, untuk mempertahankan kompatibilitas mundur untuk API mereka. Jika produsen perangkat menggunakan library Java bersama mereka sendiri melalui tag <uses-library>, bukan jalur bootclass, java_sdk_library dapat memverifikasi bahwa library Java tersebut stabil API.

java_sdk_library mengimplementasikan API SDK opsional untuk digunakan oleh aplikasi. Library yang diimplementasikan melalui java_sdk_library dalam file build (Android.bp) Anda melakukan operasi berikut:

  • Library stub dibuat untuk menyertakan stubs, stubs.system, dan stubs.test. Library stub ini dibuat dengan mengenali anotasi @hide, @SystemApi, dan @TestApi.
  • java_sdk_library mengelola file spesifikasi API (seperti current.txt) di subdirektori API. File ini diperiksa dengan kode terbaru untuk memastikan bahwa file tersebut adalah versi terbaru. Jika tidak, Anda akan menerima pesan error yang menjelaskan cara mengupdatenya. Tinjau semua perubahan update secara manual untuk memastikan perubahan tersebut sesuai dengan harapan Anda.

    Untuk mengupdate semua API, gunakan m update-api. Untuk memverifikasi bahwa API sudah yang terbaru, gunakan m checkapi.
  • File spesifikasi API diperiksa berdasarkan versi Android terbaru yang dipublikasikan untuk memastikan bahwa API kompatibel dengan versi sebelumnya dari rilis sebelumnya. Modul java_sdk_library yang disediakan sebagai bagian dari AOSP menempatkan versi yang dirilis sebelumnya di prebuilts/sdk/<latest number>.
  • Sehubungan dengan pemeriksaan file spesifikasi API, Anda dapat melakukan satu dari tiga hal berikut:
    • Izinkan pemeriksaan untuk dilanjutkan. (Jangan lakukan apa pun.)
    • Nonaktifkan pemeriksaan dengan menambahkan kode berikut ke java_sdk_library:
      unsafe_ignore_missing_latest_api: true,
    • Berikan API kosong untuk modul java_sdk_library baru dengan membuat file teks kosong bernama module_name.txt di direktori version/scope/api.
  • Jika library implementasi untuk runtime diinstal, file XML akan dibuat dan diinstal.

Cara kerja java_sdk_library

java_sdk_library yang disebut X akan membuat hal berikut:

  1. Dua salinan library implementasi: satu library bernama X dan library lainnya bernama X.impl. Library X diinstal di perangkat. Library X.impl hanya ada jika akses eksplisit ke library implementasi diperlukan oleh modul lain, seperti untuk digunakan dalam pengujian. Perhatikan bahwa akses eksplisit jarang diperlukan.
  2. Cakupan dapat diaktifkan dan dinonaktifkan untuk menyesuaikan akses. (Serupa dengan pengubah akses kata kunci Java, cakupan publik menyediakan berbagai akses; cakupan pengujian berisi API yang hanya digunakan dalam pengujian.) Untuk setiap cakupan yang diaktifkan, library akan membuat hal berikut:
    • Modul sumber stub (dari jenis modul droidstubs) - menggunakan sumber implementasi dan menghasilkan kumpulan sumber stub beserta file spesifikasi API.
    • Library stub (dari jenis modul java_library) - adalah versi stub yang dikompilasi. Library yang digunakan untuk mengompilasi ini tidak sama dengan yang disediakan ke java_sdk_library, yang memastikan detail implementasi tidak bocor ke stub API.
    • Jika Anda memerlukan library tambahan untuk mengompilasi stub, gunakan properti stub_only_libs dan stub_only_static_libs untuk menyediakannya.

Jika java_sdk_library disebut “X”, dan dikompilasi sebagai “X”, selalu rujuk dengan cara tersebut dan jangan ubah X. Build akan memilih library yang sesuai. Untuk memastikan Anda memiliki library yang paling sesuai, periksa stub untuk melihat apakah build menyebabkan error. Lakukan koreksi yang diperlukan menggunakan panduan ini:

  • Pastikan Anda memiliki library yang sesuai dengan melihat di command line dan memeriksa stub mana yang tercantum di sana untuk menentukan cakupan Anda:
    • Cakupan terlalu luas: Library dependen memerlukan cakupan API tertentu. Namun, Anda melihat API yang disertakan dalam library yang berada di luar cakupan tersebut, seperti API sistem yang disertakan dengan API publik.
    • Cakupan terlalu sempit: Library dependen tidak memiliki akses ke semua library yang diperlukan. Misalnya, library dependen harus menggunakan API sistem, tetapi mendapatkan API publik. Hal ini biasanya mengakibatkan error kompilasi karena API yang diperlukan tidak ada.
  • Untuk memperbaiki library, lakukan hanya satu dari tindakan berikut:
    • Ubah sdk_version untuk memilih versi yang Anda perlukan. ATAU
    • Tentukan library yang sesuai secara eksplisit, seperti <X>.stubs atau <X>.stubs.system.

Penggunaan java_sdk_library X

Library implementasi X digunakan saat direferensikan dari apex.java_libs. Namun, karena batasan Soong, saat library X direferensikan dari modul java_sdk_library lain dalam library APEX yang sama, X.impl secara eksplisit harus digunakan, bukan library X.

Saat java_sdk_library dirujuk dari tempat lain, library stub akan digunakan. Library stub dipilih sesuai dengan setelan properti sdk_version modul dependen. Misalnya, modul yang menentukan sdk_version: "current" menggunakan stub publik, sedangkan modul yang menentukan sdk_version: "system_current" menggunakan stub sistem. Jika kecocokan persis tidak dapat ditemukan, library stub terdekat akan digunakan. java_sdk_library yang hanya menyediakan API publik akan menyediakan stub publik untuk semua orang.

Mem-build alur dengan library Java SDK
Gambar 1. Alur build dengan library Java SDK

Contoh dan sumber

Properti srcs dan api_packages harus ada di java_sdk_library.

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

AOSP merekomendasikan (tetapi tidak mewajibkan) agar instance java_sdk_library baru secara eksplisit mengaktifkan cakupan API yang ingin digunakan. Anda juga dapat (secara opsional) memigrasikan instance java_sdk_library yang ada untuk mengaktifkan cakupan API yang akan digunakan secara eksplisit:

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

Untuk mengonfigurasi library impl yang digunakan untuk runtime, gunakan semua properti java_library normal, seperti hostdex, compile_dex, dan 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,
    }

Untuk mengonfigurasi library stub, gunakan properti berikut:

  • merge_annotations_dirs dan merge_inclusion_annotations_dirs.
  • api_srcs: Daftar file sumber opsional yang merupakan bagian dari API, tetapi bukan bagian dari library runtime.
  • stubs_only_libs: Daftar library Java yang ada di classpath saat mem-build stub.
  • hidden_api_packages: Daftar nama paket yang harus disembunyikan dari API.
  • droiddoc_options: Argumen tambahan untuk metalava.
  • droiddoc_option_files: Mencantumkan file yang dapat direferensikan dari dalam droiddoc_options menggunakan $(location <label>), dengan <file> adalah entri dalam daftar.
  • annotations_enabled.

java_sdk_library adalah java_library, tetapi bukan modul droidstubs sehingga tidak mendukung semua properti droidstubs. Contoh berikut diambil dari file build library 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,
    }

Mempertahankan kompatibilitas mundur

Sistem build memeriksa apakah API telah mempertahankan kompatibilitas mundur dengan membandingkan file API terbaru dengan file API yang dihasilkan pada waktu build. java_sdk_library melakukan pemeriksaan kompatibilitas menggunakan informasi yang diberikan oleh prebuilt_apis. Semua library yang di-build dengan java_sdk_library harus memiliki file API dalam versi terbaru api_dirs di prebuilt_apis. Saat Anda merilis versi, API mencantumkan file dan library stub yang dapat diperoleh dengan build dist dengan PRODUCT=sdk_phone_armv7-sdk.

Properti api_dirs adalah daftar direktori versi API di prebuilt_apis. Direktori versi API harus berada di tingkat direktori Android.bp.

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

Konfigurasikan direktori dengan struktur version/scope/api/ di bawah direktori prebuilt. version sesuai dengan API level dan scope menentukan apakah direktori bersifat publik, sistem, atau pengujian.

  • version/scope berisi library Java.
  • version/scope/api berisi file .txt API. Buat file teks kosong bernama module_name.txt dan module_name-removed.txt di sini.
     ├── 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