بدءًا من نظام التشغيل 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