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