Key concepts | Set up your development environment | Build an RE SDK | Consume the RE SDK | Testing, and building for distribution |
Membangun SDK yang Mendukung Runtime
Anda harus menyelesaikan langkah-langkah berikut untuk membangun SDK yang mendukung runtime:
- Menyiapkan struktur project
- Menyiapkan project dan dependensi modul
- Menambahkan logika bisnis SDK
- Menentukan API SDK
- Menentukan titik entri untuk SDK
Menyiapkan struktur project
Sebaiknya project Anda disusun ke dalam modul-modul berikut:
- Modul aplikasi - Aplikasi pengujian yang Anda gunakan untuk menguji dan mengembangkan SDK, yang mewakili apa yang akan dimiliki klien aplikasi sebenarnya. Aplikasi Anda harus memiliki dependensi pada modul library iklan yang ada (SDK berbasis runtime).
- Modul library iklan yang sudah ada (SDK berbasis runtime) - Modul library Android
yang berisi izin 'non-runtime' yang ada Logika SDK, model statis
SDK tertaut.
- Untuk memulai, kemampuan dapat dibagi. Misalnya, beberapa kode bisa ditangani oleh SDK yang sudah ada, dan beberapa dapat dirutekan ke runtime yang mendukung SDK.
- Modul library iklan yang mendukung runtime - Berisi SDK yang mendukung runtime logika bisnis. Ini dapat dibuat di Android Studio sebagai library Android ruang lingkup modul ini.
- Modul ASB yang mendukung runtime - Menentukan data paket untuk memaketkan
kode SDK yang mendukung runtime ke dalam ASB.
- Model tersebut perlu dibuat secara manual menggunakan com.android.privacy-sandbox-sdk. Anda dapat melakukan ini dengan membuat direktori baru.
- Modul ini tidak boleh berisi kode apa pun dan hanya build.gradle kosong file dengan dependensi ke modul library iklan yang mendukung runtime. Konten file ini ditentukan dalam Menyiapkan SDK.
- Ingatlah untuk menyertakan modul ini dalam file settings.gradle, dan di modul library iklan yang sudah ada.
Struktur project dalam panduan ini adalah saran, Anda dapat memilih struktur yang berbeda untuk SDK dan menerapkan prinsip teknis yang sama. Anda dapat membuat modul tambahan lainnya kapan saja untuk memodularisasi kode di aplikasi dan modul library.
Menyiapkan SDK
Untuk menyiapkan project Anda untuk pengembangan SDK yang mendukung runtime, Anda harus menentukan beberapa dependensi alat dan library terlebih dahulu:
- Library kompatibilitas mundur Runtime SDK, yang memberikan dukungan untuk
perangkat yang tidak memiliki Privacy Sandbox (Android 13 dan yang lebih lama)
(
androidx.privacysandbox.sdkruntime:
) - Library UI untuk mendukung presentasi iklan (
androidx.privacysandbox.ui:
) - Alat developer SDK untuk mendukung deklarasi API SDK dan pembuatan shim (
androidx.privacysandbox.tools:
)
Tambahkan tanda ini ke file gradle.properties project Anda untuk mengaktifkan kemampuan membuat SDK yang mendukung runtime.
# This enables the Privacy Sandbox for your project on Android Studio. android.experimental.privacysandboxsdk.enable=true android.experimental.privacysandboxsdk.requireServices=false
Ubah build.gradle project Anda untuk menyertakan library Jetpack helper dan dependensi lainnya:
// Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ext.kotlin_version = '1.9.10' ext.ksp_version = "$kotlin_version-1.0.13" ext.privacy_sandbox_activity_version = "1.0.0-alpha01" ext.privacy_sandbox_sdk_runtime_version = "1.0.0-alpha13" ext.privacy_sandbox_tools_version = "1.0.0-alpha09" ext.privacy_sandbox_ui_version = "1.0.0-alpha09" repositories { mavenCentral() } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } plugins { id 'com.android.application' version '8.4.0-alpha13' apply false id 'com.android.library' version '8.4.0-alpha13' apply false // These two plugins do annotation processing and code generation for the sdk-implementation. id 'androidx.privacysandbox.library' version '1.0.0-alpha02' apply false id 'com.google.devtools.ksp' version "$ksp_version" apply false id 'org.jetbrains.kotlin.jvm' version '1.9.10' apply false } task clean(type: Delete) { delete rootProject.buildDir }
Update file build.gradle di modul library iklan yang mendukung runtime (RE SDK) untuk menyertakan dependensi ini.
dependencies { // This allows Android Studio to parse and validate your SDK APIs. ksp "androidx.privacysandbox.tools:tools-apicompiler:$privacy_sandbox_tools_version" // This contains the annotation classes to decorate your SDK APIs. implementation "androidx.privacysandbox.tools:tools:$privacy_sandbox_tools_version" // This is runtime dependency required by the generated server shim code for // backward compatibility. implementation "androidx.privacysandbox.sdkruntime:sdkruntime-provider:$privacy_sandbox_sdk_runtime_version" // These are runtime dependencies required by the generated server shim code as // they use Kotlin. implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1' // This is the core part of the UI library to help with UI notifications. implementation "androidx.privacysandbox.ui:ui-core:$privacy_sandbox_ui_version" // This helps the SDK open sessions for the ad. implementation "androidx.privacysandbox.ui:ui-provider:$privacy_sandbox_ui_version" // This is needed if your SDK implements mediation use cases implementation "androidx.privacysandbox.ui:ui-client:$privacy_sandbox_ui_version" }
Ganti file build.gradle di modul ASB yang mendukung runtime dengan kode berikut:
plugins { id 'com.android.privacy-sandbox-sdk' } android { compileSdk 34 minSdk 21 bundle { // This is the package name of the SDK that you want to publish. // This is used as the public identifier of your SDK. // You use this later on to load the runtime-enabled SDK packageName = '<package name of your runtime-enabled SDK>' // This is the version of the SDK that you want to publish. // This is used as the public identifier of your SDK version. setVersion(1, 0, 0) // SDK provider defined in the SDK Runtime library. // This is an important part of the future backwards compatibility // support, most SDKs won't need to change it. sdkProviderClassName = "androidx.privacysandbox.sdkruntime.provider.SandboxedSdkProviderAdapter" // This is the class path of your implementation of the SandboxedSdkProviderCompat class. // It's the implementation of your runtime-enabled SDK's entry-point. // If you miss this step, your runtime-enabled SDK will fail to load at runtime: compatSdkProviderClassName = "<your-sandboxed-sdk-provider-compat-fully-qualified-class-name>" } } dependencies { // This declares the dependency on your runtime-enabled ad library module. include project(':<your-runtime-enabled-ad-library-here>') }
Update file build.gradle di modul library iklan yang ada (RA SDK) untuk menyertakan dependensi berikut:
dependencies { // This declares the client's dependency on the runtime-enabled ASB module. // ⚠️ Important: We depend on the ASB module, not the runtime-enabled module. implementation project(':<your-runtime-enabled-asb-module-here>') // Required for backwards compatibility on devices where SDK Runtime is unavailable. implementation "androidx.privacysandbox.sdkruntime:sdkruntime-client:$privacy_sandbox_sdk_runtime_version" // This is required to display banner ads using the SandboxedUiAdapter interface. implementation "androidx.privacysandbox.ui:ui-core:$privacy_sandbox_ui_version" implementation "androidx.privacysandbox.ui:ui-client:$privacy_sandbox_ui_version" // This is required to use SDK ActivityLaunchers. implementation "androidx.privacysandbox.activity:activity-core:$privacy_sandbox_activity_version" implementation "androidx.privacysandbox.activity:activity-client:$privacy_sandbox_activity_version" }
Menambahkan logika bisnis SDK
Terapkan logika bisnis SDK seperti yang biasa Anda lakukan di dalam modul library iklan yang mengaktifkan runtime.
Jika Anda memiliki SDK yang sudah ada dan akan dimigrasikan, pindahkan sebanyak mungkin logika bisnis, antarmuka, dan fungsi yang ditampilkan sistem sesuai keinginan Anda pada tahap ini, tetapi pertimbangkan migrasi penuh di masa mendatang.
Jika Anda memerlukan akses ke penyimpanan, ID Iklan Google Play, atau ID kumpulan aplikasi, baca bagian berikut:
Menggunakan storage API di SDK Anda
SDK di Runtime SDK tidak dapat lagi mengakses, membaca, atau menulis di penyimpanan internal aplikasi dan sebaliknya.
Runtime SDK diberi alokasi area penyimpanan internalnya sendiri, terpisah dari aplikasi.
SDK dapat mengakses penyimpanan internal terpisah ini menggunakan API penyimpanan file pada objek Context
yang ditampilkan oleh SandboxedSdkProvider#getContext()
.
SDK hanya dapat menggunakan penyimpanan internal, jadi hanya API penyimpanan internal, seperti Context.getFilesDir()
atau
Context.getCacheDir()
kerja. Lihat contoh lainnya di
Mengakses dari penyimpanan internal.
Akses ke penyimpanan eksternal dari Runtime SDK tidak didukung. Memanggil API untuk mengakses penyimpanan eksternal akan menampilkan pengecualian atau menampilkan null. Daftar berikut menyertakan beberapa contoh:
- Mengakses file menggunakan Storage Access Framework akan memunculkan SecurityException.
getExternalFilsDir()
selalu menampilkan null.
Anda harus menggunakan Context
yang ditampilkan oleh SandboxedSdkProvider.getContext()
untuk penyimpanan. Menggunakan API penyimpanan file pada instance objek Context
lainnya, seperti konteks aplikasi, tidak dijamin akan berfungsi seperti yang diharapkan dalam semua situasi.
Cuplikan kode berikut menunjukkan cara menggunakan penyimpanan di Runtime SDK:
class SdkServiceImpl(private val context: Context) : SdkService { override suspend fun getMessage(): String = "Hello from Privacy Sandbox!" override suspend fun createFile(sizeInMb: Int): String { val path = Paths.get( context.dataDir.path, "file.txt" ) withContext(Dispatchers.IO) { Files.deleteIfExists(path) Files.createFile(path) val buffer = ByteArray(sizeInMb * 1024 * 1024) Files.write(path, buffer) } val file = File(path.toString()) val actualFileSize: Long = file.length() / (1024 * 1024) return "Created $actualFileSize MB file successfully" } }
Dalam penyimpanan internal terpisah untuk setiap Runtime SDK, setiap SDK memiliki direktori penyimpanannya sendiri. Penyimpanan per SDK adalah pemisahan logis penyimpanan internal Runtime SDK yang membantu memperhitungkan jumlah penyimpanan yang digunakan setiap SDK.
Semua API penyimpanan internal pada objek Context
menampilkan jalur penyimpanan untuk setiap SDK.
Mengakses ID iklan yang disediakan oleh layanan Google Play
Jika SDK Anda memerlukan akses ke ID iklan yang disediakan oleh layanan Google Play, gunakan AdIdManager#getAdId()
untuk mengambil nilai secara asinkron.
Mengakses ID kumpulan aplikasi yang disediakan oleh layanan Google Play
Jika SDK Anda memerlukan akses ke ID kumpulan aplikasi yang disediakan oleh layanan Google Play, gunakan
AppSetIdManager#getAppSetId()
untuk mengambil nilai secara asinkron.
Mendeklarasikan API SDK
Agar SDK yang mengaktifkan runtime dapat diakses di luar runtime, Anda harus menentukan API yang dapat digunakan klien (RA SDK atau aplikasi klien).
Gunakan anotasi untuk mendeklarasikan antarmuka ini.
Anotasi
API SDK perlu dideklarasikan di Kotlin sebagai antarmuka dan class data menggunakan anotasi berikut:
Anotasi | |
---|---|
@PrivacySandboxService |
|
@PrivacySandboxInterface |
|
@PrivacySandboxValue |
|
@PrivacySandboxCallback |
|
Anda perlu menentukan antarmuka dan class ini di mana pun di dalam modul library iklan yang mendukung runtime.
Lihat penggunaan anotasi ini di bagian berikut.
@PrivacySandboxService
@PrivacySandboxService interface SdkService { suspend fun getMessage(): String suspend fun createFile(sizeInMb: Int): String suspend fun getBanner(request: SdkBannerRequest, requestMediatedAd: Boolean): SdkSandboxedUiAdapter? suspend fun getFullscreenAd(): FullscreenAd }
@PrivacySandboxInterface
@PrivacySandboxInterface interface SdkSandboxedUiAdapter : SandboxedUiAdapter
@PrivacySandboxValue
@PrivacySandboxValue data class SdkBannerRequest( /** The package name of the app. */ val appPackageName: String, /** * An [SdkActivityLauncher] used to launch an activity when the banner is clicked. */ val activityLauncher: SdkActivityLauncher, /** * Denotes if a WebView banner ad needs to be loaded. */ val isWebViewBannerAd: Boolean )
@PrivacySandboxCallback
@PrivacySandboxCallback interface InAppMediateeSdkInterface { suspend fun show() }
Jenis yang didukung
API SDK yang mendukung runtime mendukung jenis berikut:
- Semua tipe primitif dalam bahasa pemrograman Java (seperti int, long, karakter, boolean, dan sebagainya)
- String
- Antarmuka Kotlin yang dianotasi dengan
@PrivacySandboxInterface
atau@PrivacySandboxCallback
- Class data Kotlin yang dianotasi dengan
@PrivacySandboxValue
- java.lang.List - semua elemen dalam Daftar harus berupa salah satu data yang didukung jenis
Ada beberapa peringatan tambahan:
- Class data yang dianotasikan dengan
@PrivacySandboxValue
tidak boleh berisi kolom jenis@PrivacySandboxCallback
- Jenis nilai yang ditampilkan tidak boleh berisi jenis yang dianotasi dengan
@PrivacySandboxCallback
- Daftar tidak boleh berisi elemen dari jenis yang dianotasikan dengan
@PrivacySandboxInterface
atau@PrivacySandboxCallback
API Asinkron
Karena API SDK selalu melakukan panggilan ke proses terpisah, kita perlu memastikan bahwa panggilan ini tidak memblokir thread panggilan klien.
Untuk mencapai hal ini, semua metode dalam antarmuka dianotasi dengan
@PrivacySandboxService
, @PrivacySandboxInterface
, dan @PrivacySandboxCallback
harus dideklarasikan secara eksplisit sebagai API asinkron.
API asinkron dapat diterapkan di Kotlin dengan dua cara:
- Menggunakan fungsi penangguhan.
- Terima callback yang mendapatkan notifikasi saat operasi selesai, atau peristiwa lainnya selama progres operasi. Jenis nilai yang ditampilkan fungsi harus berupa Unit.
Pengecualian
SDK API tidak mendukung semua bentuk pengecualian yang diperiksa.
Kode shim yang dihasilkan menangkap setiap pengecualian runtime yang ditampilkan oleh SDK dan
menampilkannya sebagai PrivacySandboxException
kepada klien dengan informasi tentang
penyebab yang ada
di dalamnya.
Library UI
Jika memiliki antarmuka yang merepresentasikan Google Ads, seperti banner, Anda juga harus menerapkan antarmuka SandboxedUiAdapter
guna mengaktifkan sesi pembukaan untuk iklan yang dimuat.
Sesi-sesi ini membentuk saluran samping antara klien dan SDK, dan mereka memenuhi dua tujuan utama:
- Terima notifikasi setiap kali perubahan UI terjadi.
- Beri tahu klien tentang setiap perubahan dalam presentasi UI.
Karena klien dapat menggunakan antarmuka yang dianotasi dengan @PrivacySandboxService
untuk
dengan SDK Anda, setiap API untuk memuat iklan dapat ditambahkan ke
dalam antarmuka berbasis web
yang sederhana.
Saat klien meminta untuk memuat iklan, muat iklan tersebut dan tampilkan instance
antarmuka yang mengimplementasikan SandboxedUiAdapter
. Dengan begitu, klien dapat meminta sesi pembukaan untuk iklan tersebut.
Saat klien meminta untuk membuka sesi, SDK yang mendukung runtime dapat membuat tampilan iklan menggunakan respons iklan dan konteks yang diberikan.
Untuk melakukannya, buat class yang mengimplementasikan antarmuka SandboxedUiAdapter.Session
dan, saat SandboxedUiAdapter.openSession()
dipanggil, pastikan Anda memanggil client.onSessionOpened()
, yang meneruskan instance class Session
sebagai parameter.
class SdkSandboxedUiAdapterImpl(
private val sdkContext: Context,
private val request: SdkBannerRequest,
) : SdkSandboxedUiAdapter {
override fun openSession(
context: Context,
windowInputToken: IBinder,
initialWidth: Int,
initialHeight: Int,
isZOrderOnTop: Boolean,
clientExecutor: Executor,
client: SandboxedUiAdapter.SessionClient
) {
val session = SdkUiSession(clientExecutor, sdkContext, request)
clientExecutor.execute {
client.onSessionOpened(session)
}
}
}
Class ini juga menerima notifikasi setiap kali perubahan UI terjadi. Anda dapat Gunakan kelas ini untuk mengubah ukuran iklan, atau mengetahui ketika konfigurasi berubah, misalnya.
Pelajari lebih lanjut UI Presentation API di Runtime.
Dukungan aktivitas
Untuk memulai aktivitas milik SDK dari Privacy Sandbox, Anda perlu mengubah SDK API untuk menerima objek SdkActivityLauncher
, yang juga disediakan oleh library UI.
Misalnya, SDK API berikut harus meluncurkan aktivitas, sehingga mengharapkan parameter SdkActivityLauncher
:
@PrivacySandboxInterface
interface FullscreenAd {
suspend fun show(activityLauncher: SdkActivityLauncher)
}
Titik entri SDK
Class abstrak SandboxedSdkProvider
mengenkapsulasi API yang digunakan Runtime SDK untuk berinteraksi dengan SDK yang dimuat di dalamnya.
SDK yang mendukung runtime harus menerapkan class abstrak ini untuk membuat titik entri agar runtime SDK dapat berkomunikasi dengannya.
Untuk dukungan kompatibilitas mundur, kami telah memperkenalkan class berikut:
SandboxedSdkProviderAdapter
, yang memperluasSandboxedSdkProvider
dan menangani permintaan pemuatan SDK terlepas dari ketersediaan Runtime SDK. Ini digunakan secara internal, dideklarasikan dalam Modul ASB.SandboxedSdkProviderCompat
, class abstrak yang meniru antarmukaSandboxedSdkProvider
.
Pelajari lebih lanjut kompatibilitas mundur untuk Runtime SDK.
Alat pembuat shim menambahkan lapisan abstraksi lain: Alat tersebut menghasilkan class abstrak bernama AbstractSandboxedSdkProvider
menggunakan antarmuka yang Anda anotasikan dengan @PrivacySandboxService
.
Class ini memperluas SandboxedSdkProviderCompat
dan berada dalam paket yang sama dengan antarmuka yang dianotasi.
// Auto-generated code.
abstract class AbstractSandboxedSdkProvider : SandboxedSdkProviderCompat {
abstract fun createMySdk(context: Context): MySdk
}
Class yang dihasilkan ini menampilkan metode factory abstrak tunggal yang mengambil
Context
dan mengharapkan antarmuka yang dianotasikan titik entri Anda ditampilkan.
Metode ini diberi nama sesuai antarmuka @PrivacySandboxService
Anda, yang diawali
create
sebagai nama. Misalnya, jika antarmuka Anda bernama MySdk
, alat tersebut
menghasilkan createMySdk
.
Untuk sepenuhnya menghubungkan titik entri, Anda harus memberikan implementasi antarmuka yang dianotasi @PrivacySandboxService
di SDK yang mendukung runtime ke AbstractSandboxedSdkProvider
yang dihasilkan.
class MySdkSandboxedSdkProvider : AbstractSandboxedSdkProvider() {
override fun createMySdk(context: Context): MySdk = MySdkImpl(context)
}
Perubahan pada Modul ASB
Anda harus mendeklarasikan nama class yang sepenuhnya memenuhi syarat dari penerapan SandboxedSdkProviderCompat
di kolom compatSdkProviderClassName
pada build.gradle modul ASB.
Ini adalah class yang Anda terapkan pada langkah sebelumnya, dan Anda akan memodifikasi build.gradle di Modul ASB sebagai berikut:
bundle {
packageName = '<package name of your runtime-enabled SDK>'
setVersion(1, 0, 0)
// SDK provider defined in the SDK Runtime library.
sdkProviderClassName = "androidx.privacysandbox.sdkruntime.provider.SandboxedSdkProviderAdapter"
// This is the class that extends AbstractSandboxedSdkProvider,
// MySdkSandboxProvider as per the example provided.
compatSdkProviderClassName = "com.example.mysdk.MySdkSandboxProvider"
}
Langkah 2: Siapkan lingkungan pengembangan AndaLangkah 4: Gunakan SDK yang mendukung runtime