Mengimplementasikan library Java SDK

Platform Android berisi banyak library Java bersama yang secara opsional bisa dimasukkan dalam classpath aplikasi dengan <uses-library> di manifes aplikasi. Link aplikasi terhadap library ini, jadi perlakukan library seperti Android API lainnya dalam hal kompatibilitas, peninjauan API, dan dukungan alat. Namun, perhatikan bahwa sebagian besar {i>library<i} tidak memiliki fitur ini.

Jenis modul java_sdk_library membantu mengelola library seperti ini. Produsen perangkat dapat menggunakan mekanisme ini untuk library Java bersama, guna 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 API stabil.

java_sdk_library menerapkan API SDK opsional untuk digunakan oleh aplikasi. Library yang diterapkan melalui java_sdk_library di file build (Android.bp) melakukan operasi berikut:

  • Library stub dibuat untuk menyertakan stubs, stubs.system, dan stubs.test. Ini library stub dibuat dengan mengenali @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 itu merupakan versi saat ini. Jika tidak, Anda akan menerima pesan error yang menjelaskan cara memperbaruinya. Tinjau secara manual semua perubahan pembaruan untuk memastikan bahwa mereka sesuai dengan ekspektasi Anda.

    Untuk mengupdate semua API, gunakan m update-api. Untuk memverifikasi bahwa API sudah yang terbaru, gunakan m checkapi.
  • File spesifikasi API akan dibandingkan dengan file versi Android yang dipublikasikan untuk memastikan bahwa API tersebut kompatibel dengan versi sebelumnya dengan rilis sebelumnya. Modul java_sdk_library yang disediakan sebagai bagian dari AOSP menempatkan versi yang telah dirilis sebelumnya di prebuilts/sdk/<latest number>.
  • Sehubungan dengan pemeriksaan file spesifikasi API, Anda dapat melakukan salah satu dari tiga hal berikut:
    • Izinkan pemeriksaan dilanjutkan. (Jangan lakukan apa pun.)
    • Nonaktifkan pemeriksaan dengan menambahkan hal berikut ke java_sdk_library:
      unsafe_ignore_missing_latest_api: true,
    • Menyediakan 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 dibuat dan diinstal.

Cara kerja java_sdk_library

java_sdk_library yang disebut X membuat hal berikut:

  1. Dua salinan library implementasi: satu library bernama X dan satu lagi 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 di pengujian. Perhatikan bahwa akses eksplisit jarang diperlukan.
  2. Cakupan dapat diaktifkan dan dinonaktifkan untuk menyesuaikan akses. (Mirip dengan Java pengubah akses-kata kunci, cakupan publik menyediakan berbagai akses; suatu 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 serangkaian sumber stub bersama file spesifikasi API.
    • Library stub (dari jenis modul java_library) - adalah versi rintisan yang telah dikompilasi. {i>Library<i} yang digunakan untuk mengkompilasi ini bukan sama dengan yang diberikan ke java_sdk_library, yang memastikan detail implementasi tidak bocor ke dalam stub API.
    • Jika Anda membutuhkan library tambahan untuk mengompilasi stub, gunakan metode stub_only_libs dan stub_only_static_libs properti untuk menyediakannya.

Jika java_sdk_library disebut “X”, dan sedang dikompilasi sebagai “X”, selalu merujuknya seperti itu dan jangan mengubahnya anotasi. Build akan memilih library yang sesuai. Untuk memastikan bahwa Anda memiliki yang paling sesuai, periksa stub Anda untuk melihat apakah build yang sama. Lakukan koreksi yang diperlukan menggunakan panduan ini:

  • Verifikasi bahwa Anda memiliki perpustakaan yang sesuai dengan melihat baris perintah dan memeriksa stub yang tercantum di sana untuk menentukan cakupan Anda:
    • Cakupan terlalu luas: Library dependen memerlukan cakupan API tertentu. Tapi Anda melihat API yang disertakan dalam library, yang berada di luar cakupan tersebut, seperti API sistem yang disertakan bersama API publik.
    • Cakupan terlalu sempit: Library dependen tidak memiliki akses ke semua library yang diperlukan. Misalnya, library dependen perlu menggunakan atribut API sistem, tetapi mendapatkan API publik. Hal ini biasanya menghasilkan error kompilasi karena API yang diperlukan tidak ada.
  • Untuk memperbaiki library, hanya lakukan salah satu tindakan berikut:
    • Ubah sdk_version untuk memilih versi yang Anda butuhkan. ATAU
    • Tentukan library yang sesuai secara eksplisit, seperti <X>.stubs atau <X>.stubs.system.

Penggunaan java_sdk_library X

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

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

Alur build dengan library Java SDK
Gambar 1. Alur build dengan library Java SDK

Contoh dan sumber

Properti srcs dan api_packages harus berada 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) java_sdk_library baru tersebut secara eksplisit mengaktifkan cakupan API yang ingin digunakan. Anda juga dapat (secara opsional) migrasikan instance java_sdk_library yang ada ke secara eksplisit mengaktifkan cakupan API yang akan mereka gunakan:

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 API tetapi bukan bagian dari library runtime.
  • stubs_only_libs: Daftar library Java yang ada di classpath saat membangun stub.
  • hidden_api_packages: Daftar nama paket yang harus disembunyikan dari API.
  • droiddoc_options: Argumen tambahan untuk logamava.
  • 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 droidstubs properti baru. Contoh berikut diambil dari 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 akan memeriksa apakah API telah dipertahankan dengan versi sebelumnya kompatibilitas file dengan membandingkan file API terbaru dengan file API pada waktu build. java_sdk_library menjalankan pemeriksaan kompatibilitas menggunakan informasi yang disediakan oleh prebuilt_apis. Semua library yang dibuat dengan java_sdk_library harus memiliki file API di versi terbaru api_dirs dalam prebuilt_apis. Saat Anda merilis versi, API akan mencantumkan file dan stub library dapat diperoleh dengan build dist dengan PRODUCT=sdk_phone_armv7-sdk.

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

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

Mengonfigurasi direktori dengan version/scope/api/ di bawah direktori bawaan. version sesuai dengan level API dan scope mendefinisikan apakah direktori tersebut bersifat publik, sistem, atau untuk pengujian.

  • version/scope berisi library Java.
  • version/scope/api berisi API .txt file. 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