ความเข้ากันได้ย้อนหลังสำหรับรันไทม์ของ SDK

เอกสารนี้เสนอไลบรารี Jetpack ใหม่เพื่อช่วยนักพัฒนาซอฟต์แวร์ในการย้ายข้อมูลไปยังรันไทม์ของ SDK โดยจะอธิบายวิธีรองรับรันไทม์ของ SDK สำหรับแพลตฟอร์ม Android เวอร์ชันก่อนหน้า (ตั้งแต่การสร้างไปจนถึงการดำเนินการ) รวมถึงความแตกต่างหรือข้อจำกัดที่นักพัฒนาแอปอาจพบในสภาพแวดล้อมรันไทม์ ไลบรารีนี้ช่วยให้นักพัฒนาแอป สร้างแอปหรือ SDK เวอร์ชันเดียวซึ่งมีความสามารถในการเรียกใช้บน อุปกรณ์ที่รองรับหรือไม่รองรับรันไทม์ของ SDK

ความเข้ากันได้กับรุ่นก่อนหน้าจะทําได้ผ่านคอมโพเนนต์ต่อไปนี้

  • ปลั๊กอิน Gradle สำหรับ Android (AGP) + Bundletool สร้างตัวแปรแอปสำหรับ อุปกรณ์ที่ไม่รองรับ SDK Runtime โดยการรวม SDK Runtime ไว้ใน APK

  • ไลบรารีไคลเอ็นต์ SDK Runtime (androidx.privacysandbox.sdkruntime:sdkruntime-client) จะโหลด SDK ที่รวมไว้ จากชิ้นงานของแอปและจำลอง SDK Runtime ใน อุปกรณ์ที่ไม่รองรับ SDK Runtime

  • ไลบรารีผู้ให้บริการ SDK Runtime (androidx.privacysandbox.sdkruntime:sdkruntime-provider) มี API สำหรับ SDK เพื่ออนุญาตให้โหลดจากไลบรารีไคลเอ็นต์ SDK Runtime

การส่ง SDK ด้วย Bundletool

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

Bundletool จะสร้างชุด APK ของแอปอย่างน้อย 1 ชุดที่มี SDK ทั้งหมดที่แอป ต้องใช้ เพื่อรองรับแพลตฟอร์มเวอร์ชันที่ไม่มีการรองรับ SDK Runtime SDK แต่ละรายการจะแพ็กเกจเป็น APK แยกกัน นอกจากนี้ ระบบจะทำการแปลงต่อไปนี้

  1. คัดลอกไฟล์ไบต์โค้ด SDK (DEX) ไปยังการแยก SDK เป็นเนื้อหา
  2. คัดลอกทรัพยากร Java ของ SDK ไปยังการแยก SDK เป็นเนื้อหา
  3. แมปทรัพยากร SDK ใหม่และผสานรวมกับทรัพยากรของแอป
  4. สร้างการกำหนดค่าสำหรับไลบรารีของไคลเอ็นต์รันไทม์ของ SDK

โหลด SDK ด้วยไลบรารีไคลเอ็นต์รันไทม์ของ SDK

ไลบรารีของไคลเอ็นต์รันไทม์ของ SDK มี API ที่คล้ายกับ API ของแพลตฟอร์ม แต่รองรับทั้ง SDK ในสภาพแวดล้อมรันไทม์ของ SDK และ SDK ที่รวมอยู่ใน แอปตัวแปร

หากต้องการใช้ไลบรารีของไคลเอ็นต์รันไทม์ของ SDK ให้เพิ่มทรัพยากร Dependency androidx.privacysandbox.sdkruntime:sdkruntime-client แล้วใช้ SdkSandboxManagerCompat แทน SdkSandboxManager

เมื่อแอปพยายามโหลด SDK ไลบรารีจะตรวจสอบก่อนว่า SDK นั้น รวมอยู่ในแอปในระหว่างการสร้างหรือไม่ หากมีการรวมไว้ ไลบรารีจะแยก SDK ออกจาก SDK ที่แยกและโหลดลงในกระบวนการของแอป หากไม่ได้รวม SDK ไว้กับแอป ไลบรารีจะมอบสิทธิ์ API ของแพลตฟอร์มให้โหลด SDK

แยก SDK ออกจากชิ้นงาน

เมื่อแอปพยายามโหลด SDK ที่รวมไว้ ไลบรารีไคลเอ็นต์รันไทม์ของ SDK จะตรวจสอบ ว่ามีการแยกไฟล์ DEX ของ SDK ไปยังที่เก็บข้อมูลของอุปกรณ์แล้วหรือไม่ (code_cache) หากยังไม่ได้แยก ก็จะแยกไฟล์จากเนื้อหา

โดยปกติแล้ว ไลบรารีจะแตกไฟล์เพียงครั้งเดียวหลังจากติดตั้งหรืออัปเดตแอป

หากพื้นที่เก็บข้อมูลที่มีอยู่น้อยกว่าเกณฑ์ที่อนุญาต (ปัจจุบันคือ 100 MB) และไม่มีการแยกไฟล์ DEX ไลบรารีจะพยายามโหลด SDK โดยตรงจากเนื้อหาในอุปกรณ์ที่รองรับ (API 27 ขึ้นไป) ซึ่งจะส่งผลให้ใช้หน่วยความจำมากขึ้น

Classloader สำหรับคลาส SDK

เพื่อหลีกเลี่ยงความขัดแย้งระหว่าง SDK กับคลาสแอป ระบบจะโหลดคลาส SDK ทั้งหมด โดยใช้ ClassLoader แยกต่างหากซึ่งไม่ขึ้นอยู่กับ ClassLoader ของแอปหลัก

ในการออกแบบรันไทม์ของ SDK ปัจจุบัน การสื่อสารทั้งหมดระหว่างแอปกับ SDK จะเกิดขึ้นโดยใช้การเรียก IPC ของ Binder ออบเจ็กต์ Binder ของ SDK เดียวกันจะใช้กับ SDK ที่รวมกลุ่ม และการซีเรียลไลซ์ธุรกรรม Binder ช่วยให้นักพัฒนาแอปส่งออบเจ็กต์ Binder ของ SDK ไปยังอินเทอร์เฟซ Binder ของ SDK ในฝั่งแอปได้

สำหรับการโต้ตอบภายในอื่นๆ (เช่น การเริ่มต้น SDK, การระบุ API ของตัวควบคุมไปยัง SDK และอื่นๆ) ไลบรารีจะใช้ Reflection และ Dynamic Proxies เพื่อให้ทำงานใน ClassLoader ที่แตกต่างกันได้

สภาพแวดล้อม SDK

ไลบรารีผู้ให้บริการ SDKRuntime มี API สำหรับนักพัฒนา SDK API เหล่านี้คล้ายกับ API ของแพลตฟอร์ม แต่ช่วยให้ SDK โหลดได้ทั้งในสภาพแวดล้อม SDK Runtime และไลบรารีไคลเอ็นต์ SDKRuntime

หากต้องการใช้ SDK ของไลบรารี คุณต้องเพิ่มทรัพยากร Dependency ของ androidx.privacysandbox.sdkruntime:sdkruntime-provider และขยาย SandboxedSdkProviderCompat แทน SandboxedSdkProvider

นอกจากนี้ คุณยังต้องใช้ SandboxedSdkProviderAdapter เป็นผู้ให้บริการ SDK เพื่อ อนุญาตให้โหลดผู้ให้บริการความเข้ากันได้ในสภาพแวดล้อมรันไทม์ของ SDK

SdkSandboxControllerCompat จะมอบสิทธิ์ให้ API ของแพลตฟอร์มเมื่อโหลด SDK ในรันไทม์ของ SDK หรือมอบสิทธิ์ให้ไลบรารีไคลเอ็นต์ SDKRuntime เมื่อโหลด SDK เป็น SDK ที่รวมไว้

สำหรับ SDK ที่รวมไว้ ไลบรารีจะแก้ไขสภาพแวดล้อมของ SDK ในลักษณะที่จำลอง ลักษณะการทำงานที่คล้ายกับสภาพแวดล้อมรันไทม์ของ SDK

ส่วนถัดไปจะอธิบายลักษณะการทำงานที่คาดไว้เมื่อโหลด SDK โดยไลบรารีไคลเอ็นต์ SDKRuntime

แหล่งข้อมูล SDK

ระบบจะรองรับทรัพยากร SDK (res/) เมื่อโหลด SDK ในกระบวนการของแอป Bundletool จะผสานรวมทรัพยากรทั้งหมดของ SDK กับทรัพยากรของแอป

ระบบจะแมปทรัพยากร SDK ใหม่โดยเปลี่ยนpackageId คำนำหน้าในรหัสทรัพยากรทั้งหมดเพื่อหลีกเลี่ยงไม่ให้เกิดข้อขัดแย้ง

เมื่อไลบรารีไคลเอ็นต์ SDKRuntime โหลด SDK packageId จะได้รับการอัปเดต ในรันไทม์เพื่อให้สามารถเข้าถึงทรัพยากรที่แมปใหม่ได้โดยใช้คลาส R

แหล่งข้อมูล Java

ระบบจะรองรับทรัพยากร Java เมื่อโหลด SDK ในกระบวนการของแอป Bundletool จะคัดลอกทรัพยากร Java ของ SDK ทั้งหมดไปยังไดเรกทอรีพิเศษในชิ้นงานของแอป ไลบรารีของไคลเอ็นต์ SDKRuntime ใช้ ClassLoader ระดับกลางเพื่อเปลี่ยนเส้นทางการเรียกที่เกี่ยวข้องกับทรัพยากร Java ทั้งหมดไปยังรูทไดเรกทอรีใหม่

ชิ้นงาน SDK

ระบบจะผสานเนื้อหา SDK กับเนื้อหาแอปโดยไม่ต้องทำการแมปใหม่

ที่เก็บข้อมูล SDK

ไลบรารีไคลเอ็นต์รันไทม์ของ SDK จะสร้างรูทไดเรกทอรีเฉพาะสำหรับ SDK แต่ละรายการที่รวมไว้ในการจัดเก็บข้อมูลของแอป และจัดเตรียมบริบทพิเศษที่ใช้ไดเรกทอรีนี้เป็นรูทการจัดเก็บข้อมูลเพื่อรองรับพื้นที่เก็บข้อมูล SDK

คุณดึงบริบทนี้ได้จาก SandboxedSdkProviderCompat#getContext

วิธีการที่รองรับซึ่งเกี่ยวข้องกับพื้นที่เก็บข้อมูล

  • getDataDir
  • getCacheDir
  • getCodeCacheDir
  • getNoBackupFilesDir
  • getDir
  • getFilesDir
  • openFileInput
  • openFileOutput
  • deleteFile
  • getFileStreamPath
  • fileList
  • getDatabasePath
  • openOrCreateDatabase
  • moveDatabaseFrom - เฉพาะในบริบท SDK
  • deleteDatabase
  • databaseList
  • getSharedPreferences
  • moveSharedPreferencesFrom - เฉพาะในบริบท SDK
  • deleteSharedPreferences

คุณสร้างบริบทพื้นที่เก็บข้อมูลที่ได้รับการปกป้องของอุปกรณ์ได้โดยการเรียก createDeviceProtectedStorageContext() ในบริบทนั้น

SdkSandboxControllerCompat

ไลบรารีไคลเอ็นต์ SDKRuntime มีSdkSandboxControllerCompat การติดตั้งใช้งาน SDK ที่รวมไว้ซึ่งโหลดในกระบวนการของแอป

หากไลบรารีของไคลเอ็นต์ไม่รองรับ API (เช่น SDK ที่สร้างขึ้น ด้วยไลบรารีเวอร์ชันที่ใหม่กว่าเวอร์ชันแอป) ระบบจะใช้การทำงานสำรองที่เหมาะสมที่สุด (ไม่มีการดำเนินการหรือข้อยกเว้น)

การกำหนดเวอร์ชัน

เมื่อไลบรารีไคลเอ็นต์ SDKRuntime โหลด SDK ที่รวมไว้ จะมีการแฮนด์เชค กับไลบรารีผู้ให้บริการ SDKRuntime ภายใน SDK ในระหว่างการแฮนด์เชค ไลบรารีจะแลกเปลี่ยนเวอร์ชันและปรับลักษณะการทำงานเพื่อแทนที่ API ที่ไม่พร้อมใช้งาน ด้วยการสำรองที่เหมาะสมที่สุด (ไม่มีการดำเนินการหรือข้อยกเว้น)

เราขอแนะนำอย่างยิ่งให้ทั้งนักพัฒนาแอปและนักพัฒนา SDK ใช้ไลบรารีเวอร์ชันล่าสุด ไม่เช่นนั้นฟังก์ชันการทำงานที่ต้องได้รับการรองรับในทั้ง 2 ส่วนอาจไม่พร้อมใช้งาน

ไลบรารีไคลเอ็นต์ SDKRuntime เวอร์ชันใดก็ได้สามารถโหลด SDK ที่มีไลบรารีผู้ให้บริการ SDKRuntime เวอร์ชันใดก็ได้ และในทางกลับกัน

ในอนาคตจะมีการเปลี่ยนแปลงเป็นเวอร์ชันไลบรารีของไคลเอ็นต์ขั้นต่ำ ที่จำเป็นในการโหลด SDK ด้วยไลบรารีของผู้ให้บริการเวอร์ชันใดเวอร์ชันหนึ่ง

ซึ่งจะช่วยลดการแยกส่วนและช่วยให้มั่นใจได้ว่า API ส่วนใหญ่จะได้รับการรองรับหาก SDK ที่รวมอยู่โหลดสำเร็จ