เรียกใช้บริการ 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: ป้องกันไม่ให้บริการรีสตาร์ทโดยอัตโนมัติทุกครั้งที่หยุด

ดูข้อมูลเพิ่มเติมได้ที่Readme ภาษา Init ของ Android ใน 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