เรียกใช้บริการ 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