สร้างและใช้ SDK ที่เปิดใช้รันไทม์

1
Key concepts
2
Set up your development environment
3
Build an RE SDK
4
Consume the RE SDK
5
Testing, and building for distribution

ใช้ SDK ที่เปิดใช้รันไทม์

ส่วนนี้อธิบายวิธีที่ไคลเอ็นต์โต้ตอบกับ API ของ SDK ที่เปิดใช้รันไทม์ (RE) ที่ประกาศ

ในกรณีของคู่มือนี้ เราจะเรียกโมดูล SDK ที่มีอยู่ (หรือ SDK ที่รับรู้รันไทม์) ว่าไคลเอ็นต์

หากต้องการใช้ SDK ที่เปิดใช้รันไทม์ในแอปโดยตรง App Module คือไคลเอ็นต์

โหลด SDK ที่เปิดใช้รันไทม์

สิ่งแรกที่คุณต้องการทำใน SDK ที่รับรู้รันไทม์หรือแอปไคลเอ็นต์คือการโหลด SDK ที่เปิดใช้รันไทม์

คลาส SdkSandboxManager ช่วยในการโหลด SDK ที่เปิดใช้รันไทม์ โดยจะแสดงผลคลาส IBinder ที่ SDK ที่รับรู้รันไทม์สามารถเชื่อมโยงกับอินเทอร์เฟซที่ประกาศใน SDK ที่เปิดใช้รันไทม์ได้

คุณต้องโหลด SDK ที่เปิดใช้รันไทม์แต่ละรายการเพียงครั้งเดียว ไม่เช่นนั้น SDK manager จะแสดงข้อยกเว้น

เครื่องมือสร้าง Shim จะสร้างคลาสตัวช่วยเพื่อแปลงIBinder อินเทอร์เฟซที่ SdkSandboxManager แสดงผลกลับเป็นอินเทอร์เฟซ API ของ SDK ที่ประกาศไว้

เครื่องมือจะใช้อินเทอร์เฟซที่มีคำอธิบายประกอบด้วย @PrivacySandboxService เพื่อสร้าง *Factory คลาส

คลาสนี้มีฟังก์ชันแบบคงที่ wrapTo* ที่แปลงออบเจ็กต์ IBinder เป็นอินสแตนซ์ของอินเทอร์เฟซ SDK ที่เปิดใช้รันไทม์

SDK ที่รับรู้รันไทม์สามารถสื่อสารกับ SDK ที่เปิดใช้รันไทม์ได้โดยใช้อินเทอร์เฟซนี้ และเรียกใช้ SDK API ที่คุณประกาศไว้ในขั้นตอนก่อนหน้า

// Name of the SDK to be loaded, defined in your ASB module
private const val SDK_NAME = "com.example.sdk"

try {
    // SdkSandboxManagerCompat is used to communicate with the sandbox and load SDKs with backward compatibility.
    val sandboxManagerCompat = SdkSandboxManagerCompat.from(context)
    val sandboxedSdk = sandboxManagerCompat.loadSdk(SDK_NAME, Bundle.EMPTY)
    val mySdk = MySdkFactory.wrapToMySdk(sandboxedSdk.getInterface()!!)
} catch (e: LoadSdkCompatException) {
    Log.e(TAG, "Failed to load SDK, error code: ${e.loadSdkErrorCode}", e)
    return null
}

การใช้งานไลบรารี UI

หากต้องการใช้ไลบรารี UI เพื่อแสดงโฆษณา ให้ตรวจสอบว่าคุณได้เพิ่ม androidx.privacysandbox.ui:ui-core และ androidx.privacysandbox.ui:ui-client ลงในทรัพยากร Dependency ใน build.gradle ของ SDK ที่รับรู้รันไทม์แล้ว

โหลดโฆษณาแบนเนอร์โดยใช้ SandboxedSdkView

androidx.privacysandbox.ui:ui-client ขอแนะนำ ViewGroup ใหม่ที่ชื่อ SandboxedSdkView เพื่อโฮสต์ UI ที่สร้างโดย SDK ที่เปิดใช้รันไทม์

setAdapter() จะเปิดเซสชันด้วย SDK ที่เปิดใช้รันไทม์เพื่อ รับมุมมองโฆษณาและการแจ้งเตือนการเปลี่ยนแปลง UI เมื่อ SDK เปิดเซสชัน ระบบจะแสดงโฆษณา

โดยคุณสามารถผสานรวมได้ดังนี้

class BannerAd(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
    suspend fun loadAd() {
        // mySdk is the previously loaded SDK in the SDK Runtime.
        val bannerAd = mySdk.loadAd()
        val sandboxedSdkView = SandboxedSdkView(context)
        addViewToLayout(sandboxedSdkView)

        // This renders the ad.
        sandboxedSdkView.setAdapter(bannerAd)
        return
    }
    private fun addViewToLayout(view: View) {
        view.layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
        super.addView(view)
    }
}

นอกจากนี้ SDK ที่รับรู้รันไทม์ยังได้รับการแจ้งเตือนเมื่อสถานะเซสชันเปลี่ยนสำหรับการนำเสนอ UI ด้วย หากต้องการทำสิ่งต่อไปนี้

  1. สร้างSessionStateChangeListener()คลาสเพื่อจัดการสถานการณ์ต่างๆ ดังนี้

    private class SessionStateChangeListener() : SandboxedSdkUiSessionStateChangedListener {
        override fun onStateChanged(state: SandboxedSdkUiSessionState) {
            if (state is SandboxedSdkUiSessionState.Error) {
            // Some error has occurred while opening the session. Handle
            // accordingly.
            Log.e(TAG, state.throwable.message!!);
            } else if (state is SandboxedSdkUiSessionState.Loading) {
                // The session is attempting to be opened.
            } else if (state is SandboxedSdkUiSessionState.Active) {
                // The session is open and the UI presentation was successful.
            } else if (state is SandboxedSdkUiSessionState.Idle) {
                // There is no open session.
            }
        }
    }
    
  2. เพิ่มเครื่องมือฟังการเปลี่ยนแปลงสถานะลงใน SandboxedSdkView ที่คุณสร้างอินสแตนซ์ ไว้ก่อนหน้านี้ ระบบจะเรียกใช้ Listener ทันทีพร้อมสถานะปัจจุบันทันทีที่แนบกับมุมมอง

ข้อควรทราบ

  • หาก SDK ที่รับรู้ถึงรันไทม์เรียกใช้เมธอด SandboxedSdkView เมื่อเซสชันยังเปิดไม่เสร็จ ระบบจะใช้เอฟเฟกต์ทั้งหมดหลังจากที่เซสชันเปิดเสร็จแล้ว
    • เมธอด เช่น SandboxedSdkView.orderProviderUiAboveClientUi(providerUiOnTop)
  • ระบบไม่รองรับวิธีการเรียกที่เพิ่มหรือนำมุมมองออกจาก SandboxedSdkView (เช่น addView(), removeView(), removeViewAt() ฯลฯ) และจะแสดง UnsupportedOperationException
    • ใช้ setAdapter() เพื่อแสดงโฆษณาเท่านั้น
  • SandboxedSdkView.orderProviderUiAboveClientUi(providerUiOnTop) สลับลำดับ Z ซึ่งจะส่งผลต่อการส่ง MotionEvents จากการโต้ตอบของผู้ใช้ไปยัง SDK ที่เปิดใช้รันไทม์หรือ SDK ที่รับรู้รันไทม์

เริ่มกิจกรรม

หากต้องการเริ่มกิจกรรมที่เป็นของ SDK ที่เปิดใช้รันไทม์ ให้ใช้createSdkActivityLauncherส่วนขยายเพื่อสร้างตัวเรียกใช้ใน SDK ที่รับรู้รันไทม์

จากนั้นคุณจะส่งตัวเรียกใช้นี้ไปยัง SDK ที่เปิดใช้รันไทม์ได้ ซึ่งจะช่วยให้ SDK เริ่มกิจกรรมได้ตามต้องการ

คุณใช้ Predicate เพื่อควบคุมว่าจะเปิดใช้งานกิจกรรมหรือไม่ โดยเพรดิเคตต้องส่งคืนค่า true เพื่อให้ระบบอนุญาตกิจกรรม

val launchSdkActivityPredicate = {
    // Boolean which has to be true to launch the activities
    }
val launcher = baseActivity.createSdkActivityLauncher(launchSdkActivityPredicate)
fullscreenService.showActivity(launcher)

ลงทะเบียน SdkSandboxActivityHandlerCompat ภายใน SDK ที่เปิดใช้รันไทม์ แล้วส่งให้ SdkActivityLauncher.LaunchSdkActivity(IBinder)

fun showActivity(activityLauncher: SdkActivityLauncher) {
    val handler = object : SdkSandboxActivityHandlerCompat {
        override fun onActivityCreated(activityHolder: ActivityHolder) {
            activityHolder.getActivity().setContentView(contentView)
        }
    }

    val token = controller.registerSdkSandboxActivityHandler(handler)
    activityLauncher.launchSdkActivity(token)
}

ActivityHolder ที่ส่งไปยัง SdkSandboxActivityHandlerCompat.onActivityCreated(ActivityHolder) จะใช้ LifecycleOwner ซึ่งทำให้ SDK ที่เปิดใช้รันไทม์เข้าถึงวงจรของกิจกรรมได้

นอกจากนี้ ยังมี getOnBackPressedDispatcher API ซึ่งใช้เพื่อ ลงทะเบียนอินสแตนซ์ getOnBackPressedCallback เพื่อจัดการลักษณะการทำงานของปุ่มย้อนกลับ ภายในกิจกรรมได้ด้วย


ขั้นตอนที่ 3: สร้าง SDK ที่เปิดใช้รันไทม์ ขั้นตอนที่ 5: ทดสอบและสร้างเพื่อการจัดจำหน่าย