Menerapkan Perpustakaan Java SDK

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

Jenis modul java_sdk_library membantu mengelola perpustakaan semacam ini. Produsen perangkat dapat menggunakan mekanisme ini untuk pustaka Java bersama mereka, guna menjaga kompatibilitas mundur untuk API mereka. Jika produsen perangkat menggunakan pustaka Java bersama mereka melalui tag <uses-library> alih-alih jalur bootclass, java_sdk_library dapat memverifikasi bahwa pustaka Java tersebut stabil terhadap API.

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

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

    Untuk memperbarui semua API, gunakan m update-api . Untuk memverifikasi bahwa API adalah yang terbaru, gunakan m checkapi .
  • File spesifikasi API diperiksa berdasarkan versi Android terbaru yang diterbitkan untuk memastikan bahwa API tersebut kompatibel dengan 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 salah satu dari tiga hal berikut:
    • Biarkan pemeriksaan dilanjutkan. (Jangan lakukan apa pun.)
    • Nonaktifkan pemeriksaan dengan menambahkan yang berikut ke java_sdk_library :
      unsafe_ignore_missing_latest_api: true,
    • Sediakan API kosong untuk modul java_sdk_library baru dengan membuat file teks kosong bernama module_name.txt di direktori version/scope/api .
  • Jika pustaka implementasi untuk runtime diinstal, file XML akan dibuat dan diinstal.

Cara kerja java_sdk_library

java_sdk_library bernama X menciptakan yang berikut:

  1. Dua salinan perpustakaan implementasi: satu perpustakaan bernama X dan lainnya bernama X.impl . Library X diinstal pada perangkat. Pustaka X.impl hanya ada jika akses eksplisit ke pustaka implementasi diperlukan oleh modul lain, misalnya untuk digunakan dalam pengujian. Perhatikan bahwa akses eksplisit jarang diperlukan.
  2. Cakupan dapat diaktifkan dan dinonaktifkan untuk menyesuaikan akses. (Mirip dengan pengubah akses kata kunci Java, cakupan publik menyediakan jangkauan akses yang luas; cakupan pengujian berisi API yang hanya digunakan dalam pengujian.) Untuk setiap cakupan yang diaktifkan, pustaka akan membuat hal berikut:
    • Modul sumber stub (dari jenis modul droidstubs ) - menggunakan sumber implementasi dan mengeluarkan sekumpulan sumber rintisan bersama dengan file spesifikasi API.
    • Perpustakaan stub (dari tipe modul java_library ) - adalah versi stub yang dikompilasi. Lib yang digunakan untuk mengkompilasi ini tidak sama dengan yang disediakan ke java_sdk_library , yang memastikan detail implementasi tidak bocor ke dalam stub API.
    • Jika Anda memerlukan perpustakaan tambahan untuk mengkompilasi stub, gunakan properti stub_only_libs dan stub_only_static_libs untuk menyediakannya.

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

  • Verifikasi bahwa Anda memiliki perpustakaan yang sesuai dengan melihat pada baris perintah dan memeriksa stub mana yang terdaftar di sana untuk menentukan cakupan Anda:
    • Cakupan terlalu luas: Pustaka yang bergantung memerlukan cakupan API tertentu. Namun Anda melihat API yang disertakan dalam pustaka berada di luar cakupan tersebut, seperti API sistem yang disertakan dengan API publik.
    • Cakupan terlalu sempit: Pustaka yang bergantung tidak memiliki akses ke semua pustaka yang diperlukan. Misalnya, pustaka yang bergantung perlu menggunakan API sistem, namun mendapatkan API publik sebagai gantinya. Hal ini biasanya mengakibatkan kesalahan kompilasi karena API yang diperlukan tidak ada.
  • Untuk memperbaiki perpustakaan, lakukan hanya salah satu hal berikut:
    • Ubah sdk_version untuk memilih versi yang Anda perlukan. ATAU
    • Tentukan secara eksplisit perpustakaan yang sesuai, seperti <X>.stubs atau <X>.stubs.system .

java_sdk_library X penggunaan

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

Ketika java_sdk_library direferensikan dari tempat lain, perpustakaan stubs digunakan. Pustaka stubs dipilih sesuai dengan pengaturan properti sdk_version modul yang bergantung. 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, perpustakaan stub terdekat akan digunakan. java_sdk_library yang hanya menyediakan API publik akan menyediakan stub publik untuk semua orang.

Bangun aliran dengan perpustakaan Java SDK
Gambar 1. Alur build dengan pustaka 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 mengharuskan) instance java_sdk_library baru secara eksplisit mengaktifkan cakupan API yang ingin mereka gunakan. Anda juga dapat (secara opsional) memigrasikan instance java_sdk_library yang ada untuk secara eksplisit mengaktifkan cakupan API yang akan mereka gunakan:

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

Untuk mengonfigurasi pustaka impl yang digunakan saat 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 pustaka 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 perpustakaan runtime.
  • stubs_only_libs : Daftar perpustakaan Java yang ada di classpath saat membuat 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> merupakan entri dalam daftar.
  • annotations_enabled .

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

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

Properti api_dirs adalah daftar direktori versi API di prebuilt_apis . Direktori versi API harus ditempatkan 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 level API dan scope menentukan apakah direktori bersifat publik, sistem, atau pengujian.

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