Kompatibilitas mundur untuk Runtime SDK

Dokumen ini menyarankan library Jetpack baru untuk membantu developer melakukan migrasi ke Runtime SDK. Dokumen ini menjelaskan bagaimana Runtime SDK akan didukung untuk versi platform Android sebelumnya (dari build hingga eksekusi), dan perbedaan atau batasan dalam lingkungan runtime yang akan ditemukan oleh developer. Library ini memungkinkan developer membuat satu versi aplikasi atau SDK yang menyertakan kemampuan untuk berjalan di perangkat dengan atau tanpa dukungan Runtime SDK.

Kompatibilitas mundur dicapai melalui komponen berikut:

  • Plugin Android Gradle (AGP) + Bundletool membangun varian aplikasi untuk perangkat tanpa dukungan Runtime SDK dengan memaketkan Runtime SDK ke dalam APK.

  • Library klien Runtime SDK (androidx.privacysandbox.sdkruntime:sdkruntime-client) memuat SDK yang dipaketkan dari aset aplikasi dan mengemulasi Runtime SDK di perangkat tanpa dukungan Runtime SDK.

  • Library penyedia Runtime SDK (androidx.privacysandbox.sdkruntime:sdkruntime-provider) menyediakan API untuk SDK agar memungkinkan pemuatan dari library klien Runtime SDK.

Pengiriman SDK dengan Bundletool

Pada perangkat yang memiliki dukungan Runtime SDK, SDK akan dikirim dan diinstal sebagai paket terpisah.

Untuk mendukung versi platform yang tidak memiliki dukungan Runtime SDK, Bundletool akan membangun satu atau beberapa varian rangkaian APK aplikasi yang menyertakan semua SDK yang menjadi dependensi aplikasi. Setiap SDK dipaketkan sebagai bagian APK terpisah. Selain itu, transformasi berikut akan dilakukan:

  1. Menyalin file bytecode (DEX) SDK ke bagian SDK sebagai aset.
  2. Menyalin resource Java SDK ke bagian SDK sebagai aset.
  3. Memetakan ulang resource SDK dan menggabungkannya dengan resource aplikasi.
  4. Membuat konfigurasi untuk library klien Runtime SDK.

Memuat SDK dengan library klien Runtime SDK

Library klien Runtime SDK menyediakan API yang mirip dengan API platform, tetapi mendukung SDK di lingkungan Runtime SDK dan SDK yang dipaketkan dengan aplikasi varian.

Untuk menggunakan library klien Runtime SDK, tambahkan dependensi androidx.privacysandbox.sdkruntime:sdkruntime-client, lalu gunakan SdkSandboxManagerCompat, bukan SdkSandboxManager.

Saat aplikasi mencoba memuat SDK, library akan memeriksa terlebih dahulu apakah SDK tersebut dipaketkan dengan aplikasi selama proses membangun. Jika dipaketkan, library akan mengekstrak SDK dari bagian SDK dan memuatnya ke dalam proses aplikasi. Jika SDK tidak dipaketkan dengan aplikasi, library akan mendelegasikan API platform untuk memuat SDK.

Mengekstrak SDK dari aset

Saat aplikasi mencoba memuat SDK yang dipaketkan, library klien Runtime SDK akan memeriksa apakah file DEX SDK telah diekstrak ke penyimpanan perangkat (code_cache). Jika belum, library klien akan mengekstraknya dari aset.

Library biasanya akan mengekstrak file hanya satu kali setelah penginstalan atau update aplikasi.

Jika ruang penyimpanan yang tersedia kurang dari nilai minimum yang diizinkan (saat ini 100 MB) dan tidak ada file DEX yang diekstrak, library akan mencoba memuat SDK langsung dari aset pada perangkat yang didukung (API 27+). Hal ini menghasilkan jejak memori yang lebih besar.

Classloader untuk class SDK

Untuk menghindari konflik antara SDK dan class aplikasi, semua class SDK dimuat menggunakan classloader terpisah yang sepenuhnya independen dari classloader aplikasi utama.

Dalam desain Runtime SDK saat ini, semua komunikasi antara aplikasi dan SDK terjadi menggunakan panggilan Binder IPC. Objek Binder SDK yang sama digunakan untuk SDK yang dipaketkan, dan serialisasi transaksi Binder memungkinkan developer aplikasi mentransmisikan objek Binder SDK ke Antarmuka Binder SDK di aplikasi.

Untuk interaksi internal lainnya (seperti menginisialisasi SDK, menyediakan API pengontrol ke SDK, dan sebagainya), library ini menggunakan Refleksi dan Proxy Dinamis agar dapat berfungsi di berbagai classloader.

Lingkungan SDK

Library Penyedia SDKRuntime menyediakan API untuk developer SDK. API ini mirip dengan API platform, tetapi memungkinkan SDK dimuat oleh lingkungan Runtime SDK dan library Klien SDKRuntime.

Agar dapat menggunakan SDK library, Anda perlu menambahkan dependensi androidx.privacysandbox.sdkruntime:sdkruntime-provider dan memperluas SandboxedSdkProviderCompat, bukan SandboxedSdkProvider.

Anda juga harus menggunakan SandboxedSdkProviderAdapter sebagai penyedia SDK, agar penyedia compat dapat dimuat di lingkungan Runtime SDK.

SdkSandboxControllerCompat didelegasikan ke API platform saat SDK dimuat di Runtime SDK atau didelegasikan ke library Klien SDKRuntime saat SDK dimuat sebagai SDK yang dipaketkan.

Untuk SDK yang dipaketkan, library memodifikasi lingkungan SDK dengan cara mengemulasi perilaku yang mirip dengan lingkungan Runtime SDK.

Bagian selanjutnya menjelaskan perilaku yang diharapkan saat SDK dimuat oleh library Klien SDKRuntime.

Resource SDK

Resource SDK (res/) didukung saat SDK dimuat dalam proses aplikasi. Bundletool menggabungkan semua resource SDK dengan resource aplikasi.

Untuk menghindari konflik, resource SDK dipetakan ulang dengan mengubah awalan packageId di semua ID resource.

Saat SDK dimuat oleh library Klien SDKRuntime, packageId akan diupdate dalam runtime untuk memungkinkan penanganan resource yang dipetakan ulang menggunakan class R.

Resource Java

Resource Java didukung saat SDK dimuat dalam proses aplikasi. Bundletool menyalin semua resource Java SDK ke direktori khusus di aset aplikasi. Library Klien SDKRuntime menggunakan classloader perantara untuk mengalihkan semua panggilan terkait resource Java ke direktori root yang baru.

Aset SDK

Aset SDK digabungkan dengan aset aplikasi tanpa pemetaan ulang.

Penyimpanan SDK

Untuk mendukung Penyimpanan SDK, library Klien Runtime SDK membuat direktori root khusus untuk setiap paket SDK dalam penyimpanan aplikasi dan menyediakan konteks khusus yang menggunakan direktori ini sebagai root penyimpanan.

Konteks ini dapat diambil dari SandboxedSdkProviderCompat#getContext.

Metode terkait penyimpanan yang didukung:

  • getDataDir
  • getCacheDir
  • getCodeCacheDir
  • getNoBackupFilesDir
  • getDir
  • getFilesDir
  • openFileInput
  • openFileOutput
  • deleteFile
  • getFileStreamPath
  • fileList
  • getDatabasePath
  • openOrCreateDatabase
  • moveDatabaseFrom - hanya antar-konteks SDK
  • deleteDatabase
  • databaseList
  • getSharedPreferences
  • moveSharedPreferencesFrom - hanya antar-konteks SDK
  • deleteSharedPreferences

Konteks penyimpanan yang dilindungi perangkat dapat dibuat dengan memanggil createDeviceProtectedStorageContext() pada konteks tersebut.

SdkSandboxControllerCompat

Library Klien SDKRuntime menyediakan implementasi SdkSandboxControllerCompat untuk paket SDK yang dimuat dalam proses aplikasi.

Jika API tidak didukung oleh library klien (misalnya dengan SDK yang dibuat dengan versi library yang lebih baru daripada versi aplikasi), penggantian yang paling sesuai akan digunakan (tanpa pengoperasian atau pengecualian).

Pembuatan versi

Saat library Klien SDKRuntime memuat SDK yang dipaketkan, library ini melakukan handshake dengan library Penyedia SDKRuntime di dalam SDK. Selama handshake, library bertukar info versinya dan menyesuaikan perilaku untuk mengganti API yang tidak tersedia dengan penggantian yang paling sesuai (tanpa pengoperasian atau pengecualian).

Penggunaan library versi terbaru sangat direkomendasikan untuk Developer SDK dan aplikasi. Jika tidak, fungsi yang memerlukan dukungan di kedua bagian mungkin tidak tersedia.

Semua versi library Klien SDKRuntime dapat memuat SDK dengan versi library Penyedia SDKRuntime apa pun dan sebaliknya.

Pada masa mendatang, aturan tersebut akan diubah ke versi library klien minimal yang diperlukan untuk memuat SDK dengan versi library penyedia tertentu.

Hal ini akan meminimalkan fragmentasi dan membantu memastikan bahwa sebagian besar API akan didukung jika SDK yang dipaketkan berhasil dimuat.