Kompatibilitas mundur untuk Runtime SDK

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

Kompatibilitas mundur dicapai melalui komponen berikut:

  • Plugin Android Gradle (AGP) + Bundletool mem-build varian aplikasi untuk perangkat yang tidak memiliki 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 dapat memuat 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 mem-build satu atau beberapa varian rangkaian APK aplikasi yang menyertakan semua SDK yang menjadi dependensi aplikasi. Setiap SDK dikemas sebagai pemisahan APK terpisah. Selain itu, transformasi berikut dilakukan:

  1. Salin file bytecode (DEX) SDK ke pemisahan SDK sebagai aset.
  2. Salin resource Java SDK ke pemisahan SDK sebagai aset.
  3. Petakan ulang resource SDK dan gabungkan dengan resource aplikasi.
  4. Membuat konfigurasi untuk library klien Runtime SDK.

Memuat SDK dengan library klien SDK Runtime

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 build. Jika dipaketkan, library akan mengekstrak SDK dari pemisahan 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), dan jika belum, akan mengekstraknya dari aset.

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

Jika ruang penyimpanan yang tersedia kurang dari batas 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 SDK Binder yang sama digunakan untuk paket SDK, dan serialisasi transaksi Binder memungkinkan developer aplikasi mentransmisikan objek Binder SDK ke Antarmuka Binder SDK di sisi aplikasi.

Untuk interaksi internal lainnya (seperti menginisialisasi SDK, menyediakan API pengontrol ke SDK, dan sebagainya), library ini menggunakan Refleksi dan Proxy Dinamis untuk bekerja di berbagai classloader yang berbeda.

Lingkungan SDK

Library Penyedia SDKRuntime menyediakan API untuk developer SDK. API ini mirip dengan API platform, tetapi memungkinkan SDK untuk 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 paket SDK, library memodifikasi lingkungan SDK dengan cara yang mengemulasi perilaku yang mirip dengan lingkungan Runtime SDK.

Bagian berikutnya 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 diperbarui 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 utama yang baru.

Aset SDK

Aset SDK digabungkan dengan aset aplikasi tanpa pemetaan ulang.

Penyimpanan SDK

Untuk mendukung SDK Storage, library Klien Runtime SDK membuat direktori root khusus untuk setiap SDK yang dipaketkan dalam penyimpanan aplikasi dan memberikan 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 di antara konteks SDK
  • deleteDatabase
  • databaseList
  • getSharedPreferences
  • moveSharedPreferencesFrom - hanya di antara 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 di-build 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 akan melakukan handshake dengan library Penyedia SDKRuntime di dalam SDK. Selama handshake, library menukar 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 aplikasi dan SDK. 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.

Di masa mendatang, persyaratan 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.