ตั้งแต่ 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
การรับบริการ
หากต้องการเรียกบริการที่ขี้เกียจ ต้องเริ่มบริการแล้วจึงเรียกข้อมูล การเรียก getService
บนตัวจัดการบริการจะเริ่มต้นบริการ แต่โดยปกติแล้ว คุณต้องการรับบริการทันทีที่พร้อมให้บริการ และควรใช้ตัวแปร waitForService
ดู เอกสารประกอบเฉพาะแบ็กเอนด์ เกี่ยวกับวิธีการใช้งานเหล่านี้
ปล่อยบริการ
การปิดระบบแบบไดนามิกจะขึ้นอยู่กับการนับการอ้างอิง ดังนั้นลูกค้าจะต้องไม่ระงับการบริการเมื่อไม่ได้ใช้งาน
ตัวอย่าง:
งดการปิดระบบชั่วคราว
หากคุณต้องการให้บริการทำงานอย่างอิสระจนกว่างานบางอย่างจะเสร็จสิ้น จากนั้นจึงเปลี่ยนไปใช้การทำงานแบบไดนามิก คุณสามารถใช้ LazyServiceRegistrar::forcePersist
เพื่อสลับเปิดและปิดการปิดระบบแบบไดนามิกได้ หากสิ่งนี้ถูกเรียกจากฝั่งเซิร์ฟเวอร์ ก็ควรจะถูกเรียกก่อน registerService
ตัวอย่าง: apexservice