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