החל מ-Android 11, אפשר להפעיל ולהפסיק באופן דינמי שירותי AIDL מקוריים שפועלים במחיצת המערכת, לפי הצורך. שירותים דינמיים מתחילים לפעול כשמתקבלת בקשה להשתמש בהם, ומפסיקים לפעול אוטומטית כשאין בהם יותר שימוש.
שירותים שיכולים לפעול באופן דינמי
התכונה הזו זמינה רק לשירותים מקוריים שאפשר לשלוט במחזור החיים שלהם באמצעות init
ו-servicemanager
. אין תמיכה בשירותים בחבילות של אפליקציות, ובמקומם צריך להשתמש בשירותים מאוגדים.
הכיבוי הדינמי פועל על ידי כיבוי התהליך שבו השירות פועל. אם קיימים כמה שירותים באותו תהליך, כולם צריכים להיות רשומים כשירותים דינמיים כדי שהם יהיו תואמים לתכונה הזו. התהליך הזה יושבת כשאף אחד מהשירותים לא יהיה בשימוש.
הגדרת קובץ init .rc של שירות
כדי להפעיל שירות באופן דינמי, מוסיפים את האפשרויות הבאות לקובץ init
.rc
של השירות אחרי השורה הראשונה service <name> <cmd>
.
interface aidl serviceName
disabled
oneshot
האפשרויות האלה מבצעות את הפעולות הבאות:
-
interface aidl serviceName
: מאפשר ל-servicemanager
למצוא את השירות. אם השירות משתמש בכמה ממשקי API, צריך להצהיר על כל ממשק בשורה נפרדת. השמות האלה צריכים להיות בדיוק מה ש-servicemanager
מצפה, והם יכולים להיות שונים משם התהליך. -
disabled
: מונע את הפעלת השירות באופן אוטומטי בזמן האתחול. -
oneshot
: מונע את ההפעלה מחדש של השירות בכל פעם שהוא מופסק.
מידע נוסף זמין בקובץ ה-Readme של שפת Android Init ב-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
. במסמכי התיעוד הספציפיים ל-backend מוסבר איך להשתמש בהם.
השקת השירות
הכיבוי הדינמי מבוסס על ספירת הפניות, ולכן הלקוחות לא יכולים להחזיק בשירות כשהוא לא בשימוש.
לדוגמה:
השבתה זמנית של הכיבוי
אם רוצים ששירות יפעל באופן עצמאי עד להשלמת משימות מסוימות ואז יעבור להתנהגות דינמית, אפשר להשתמש ב-LazyServiceRegistrar::forcePersist
כדי להפעיל או להשבית את ההשבתה הדינמית. אם הפונקציה הזו נקראת בצד השרת, צריך לקרוא לה לפני registerService
.
דוגמה: apexservice