تشغيل خدمات AIDL ديناميكيًا

بدءًا من نظام التشغيل Android 11، يمكن بدء تشغيل خدمات AIDL الأصلية التي تعمل في قسم النظام وإيقافها ديناميكيًا حسب الحاجة. تبدأ الخدمات الديناميكية عند طلبها لأول مرة وتتوقف تلقائيًا عندما لا تكون قيد الاستخدام.

الخدمات التي يمكن تشغيلها بشكل ديناميكي

لا تتوفر هذه الميزة إلا للخدمات الأصلية التي يمكن التحكّم في مراحل نشاطها من خلال init وservicemanager. الخدمات داخل حِزم التطبيقات غير متاحة، ويجب أن تستخدم خدمات مرتبطة بدلاً من ذلك.

يعمل إيقاف التشغيل الديناميكي عن طريق إيقاف العملية التي يتم فيها تشغيل الخدمة. وفي حال توفُّر عدة خدمات في العملية نفسها، يجب أن تكون جميعها مسجَّلة على أنّها ديناميكية حتى تتوافق مع هذه الميزة. سيتم إيقاف هذه العملية بعد ذلك عندما لا يتم استخدام جميع الخدمات.

ضبط ملف init .rc للخدمة

لتشغيل خدمة بشكل ديناميكي، أضِف الخيارات التالية إلى ملف init .rc الخاص بالخدمة بعد سطر service <name> <cmd> في البداية.

interface aidl serviceName
disabled
oneshot

تؤدي هذه الخيارات إلى ما يلي:

  • interface aidl serviceName: يسمح هذا الإذن servicemanager بالعثور على الخدمة. إذا كانت الخدمة تستخدم واجهات متعددة، يُرجى توضيح كل واجهة على حدة. يجب أن تتطابق هذه الأسماء بالضبط مع ما يتوقّعه servicemanager وقد تختلف عن اسم العملية.
  • disabled: يمنع بدء الخدمة تلقائيًا عند بدء التشغيل.
  • oneshot: يمنع إعادة تشغيل الخدمة تلقائيًا في كل مرة يتم إيقافها.

للحصول على مزيد من المعلومات، يمكنك الاطّلاع على الإصدار التمهيدي للغة 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