הרצה דינמית של שירותי AIDL

החל מ-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