تشغيل خدمات 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 في 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 .

على سبيل المثال: خدمة أبيكس