بدءًا من 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 Readme في مشروع 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