تشغيل خدمات 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: يمنع إعادة تشغيل الخدمة تلقائيًا في كل مرة يتم فيها إيقافها.

لمزيد من المعلومات، يُرجى الاطّلاع على ملف 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 لإيقاف الخدمات استنادًا إلى أعداد الإحالات.

أمثلة:

ضبط برامج خدمة لغة تعريف واجهة نظام Android ‏(AIDL)

الحصول على الخدمة

لاسترداد خدمة بطيئة، يجب تشغيل الخدمة ثم استردادها. سيؤدي الاتصال بـ getService في مدير الخدمة إلى بدء الخدمة، ولكنك تريد عادةً الحصول على الخدمة فور توفّرها، ويجب استخدام waitForService الصيغ. اطّلِع على المستندات المتعلّقة بالجانب العميق لمعرفة كيفية استخدام هذه العناصر.

إتاحة الخدمة

يستند الإيقاف الديناميكي إلى احتساب عدد الإحالات، لذا يجب ألا يحتفظ العملاء بالخدمة عندما لا تكون قيد الاستخدام.

أمثلة:

إيقاف ميزة "الإيقاف" مؤقتًا

إذا كنت تريد تشغيل خدمة بشكل مستقل إلى أن تكتمل مهام معيّنة ثم التبديل إلى السلوك الديناميكي، يمكنك استخدام LazyServiceRegistrar::forcePersist لتفعيل وضع الإيقاف/التشغيل الديناميكي وإيقافه. إذا كان يتم استدعاء هذا الإجراء من جهة الخادم، يجب استدعاؤه قبل registerService.

مثال: apexservice