เรียกใช้บริการ AIDL แบบไดนามิก

ตั้งแต่ Android 11 เป็นต้นไป บริการ AIDL ดั้งเดิมที่ทำงานใน พาร์ติชันระบบจะเริ่มและหยุดได้แบบไดนามิกตามความจำเป็น บริการแบบไดนามิกจะเริ่มทำงานเมื่อมีการขอใช้ครั้งแรกและจะหยุดทำงานโดยอัตโนมัติเมื่อ ไม่มีการใช้งานอีกต่อไป

บริการที่เรียกใช้แบบไดนามิกได้

ฟีเจอร์นี้ใช้ได้เฉพาะกับบริการดั้งเดิมที่init และ servicemanager ควบคุมวงจรของบริการได้ ระบบไม่รองรับบริการภายในแพ็กเกจแอป และควรใช้บริการที่เชื่อมโยงแทน

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

กำหนดค่าไฟล์ init .rc ของบริการ

หากต้องการเรียกใช้บริการแบบไดนามิก ให้เพิ่มตัวเลือกต่อไปนี้ลงในไฟล์ init .rc ของบริการหลังบรรทัด service <name> <cmd> แรก

interface aidl serviceName
disabled
oneshot

ตัวเลือกเหล่านี้จะทำสิ่งต่อไปนี้

  • interface aidl serviceName: อนุญาตให้ servicemanager ค้นหาบริการ หากบริการใช้อินเทอร์เฟซหลายรายการ ให้ประกาศแต่ละอินเทอร์เฟซในบรรทัดของตัวเอง ชื่อเหล่านี้ต้องตรงกับที่ servicemanager คาดหวังและอาจแตกต่างจากชื่อกระบวนการ
  • disabled: ป้องกันไม่ให้บริการเริ่มทำงานโดยอัตโนมัติเมื่อเปิดเครื่อง
  • oneshot: ป้องกันไม่ให้บริการรีสตาร์ทโดยอัตโนมัติทุกครั้งที่มีการหยุดบริการ

ดูข้อมูลเพิ่มเติมได้ที่ Android Init Language Readme ใน AOSP

ตัวอย่าง

ลงทะเบียนบริการ

บริการแต่ละรายการจะสร้างและลงทะเบียนกับ servicemanager โดยปกติแล้ว การลงทะเบียนจะ เกิดขึ้นในไฟล์ชื่อ main.cpp แต่การใช้งานอาจแตกต่างกันไป โดย การจดทะเบียนมักจะมีลักษณะดังนี้

using android::defaultServiceManager;

defaultServiceManager()->addService(serviceName, service);

บางครั้ง BinderService::publish หรือ BinderService::instantiate จะทำการลงทะเบียนโดยเรียกใช้โค้ดด้านบน

หากต้องการลงทะเบียนบริการเป็นแบบไดนามิก ให้แทนที่รหัสการลงทะเบียนด้วยรหัสต่อไปนี้

#include <binder/LazyServiceRegistrar.h>

using android::binder::LazyServiceRegistrar;

auto lazyRegistrar = LazyServiceRegistrar::getInstance();
lazyRegistrar.registerService(service, serviceName);

servicemanager สื่อสารกับ LazyServiceRegistrar เพื่อปิดบริการ ตามจำนวนการอ้างอิง

ตัวอย่าง

กำหนดค่าไคลเอ็นต์บริการ AIDL

รับบริการ

หากต้องการเรียกข้อมูลบริการที่โหลดแบบ Lazy คุณต้องเริ่มบริการก่อน แล้วจึงเรียกข้อมูล การเรียก getService ในผู้จัดการบริการจะเริ่มบริการ แต่โดยปกติแล้ว คุณต้องการรับบริการทันทีที่พร้อมใช้งาน และควรใช้ตัวแปร waitForService ดูเอกสารประกอบเฉพาะแบ็กเอนด์ เกี่ยวกับวิธีใช้

เผยแพร่บริการ

การปิดระบบแบบไดนามิกจะอิงตามการนับการอ้างอิง ดังนั้นไคลเอ็นต์จึงต้องไม่ยึด บริการไว้เมื่อไม่ได้ใช้งาน

ตัวอย่าง

ปิดใช้การปิดระบบชั่วคราว

หากต้องการให้บริการทำงานอย่างอิสระจนกว่างานบางอย่างจะเสร็จสมบูรณ์ แล้วจึงเปลี่ยนไปใช้ลักษณะการทำงานแบบไดนามิก คุณสามารถใช้ LazyServiceRegistrar::forcePersist เพื่อเปิดและปิดการปิดระบบแบบไดนามิกได้ หากเรียกใช้จากฝั่งเซิร์ฟเวอร์ ควรเรียกใช้ก่อน registerService

ตัวอย่างเช่น apexservice