أرسلت بواسطة أليس يوان، كبير مهندسي علاقات المطورين
اعترافًا بأن الاستنزاف المفرط للبطارية هو أهم أولويات مستخدمي Android، اتخذت Google خطوات مهمة لمساعدة المطورين على إنشاء تطبيقات أكثر كفاءة في استخدام الطاقة. على 1 مارس 2026، بدأ متجر Google Play في طرح معالجات الجودة التقنية لقفل الاستيقاظ لتحسين استنزاف البطارية. سيتم طرح هذا العلاج تدريجيًا على التطبيقات المتأثرة خلال الأسابيع التالية. قد تشهد التطبيقات التي تتجاوز باستمرار حد “قفل التنشيط الجزئي الزائد” في مؤشرات Android الحيوية تأثيرات ملموسة على تواجدها في المتجر، بما في ذلك تحذيرات على قائمة متجرهم والاستبعاد من أسطح الاكتشاف مثل التوصيات.
قد يرى المستخدمون تحذيرًا في بطاقة بيانات متجرك إذا تجاوز تطبيقك حد السلوك السيئ.
أدت هذه المبادرة إلى رفع كفاءة البطارية إلى مقياس حيوي أساسي إلى جانب مقاييس الاستقرار مثل الأعطال وأخطاء ANR. يتم تعريف “عتبة السلوك السيئ” على أنها الاحتفاظ بقفل تنشيط جزئي غير معفى لمدة على الأقل ساعتين في المتوسط أثناء إيقاف تشغيل الشاشة لأكثر من 5% من جلسات المستخدم في 28 يومًا الماضية. يتم استثناء قفل التنشيط إذا كان قفل التنشيط مثبتًا على النظام ويوفر فوائد واضحة للمستخدم لا يمكن تحسينها بشكل أكبر، مثل تشغيل الصوت أو الوصول إلى الموقع أو نقل البيانات التي يبدأها المستخدم. يمكنك عرض التعريف الكامل لأقفال التنشيط المفرطة في موقعنا وثائق مؤشرات Android الحيوية.
كجزء من مبادرتنا المستمرة لتحسين عمر البطارية عبر نظام Android البيئي، قمنا بتحليل آلاف التطبيقات وكيفية استخدامها لأقفال التنشيط الجزئية. على الرغم من أن أقفال التنشيط ضرورية في بعض الأحيان، إلا أننا غالبًا ما نرى تطبيقات تحتفظ بها بشكل غير فعال أو غير ضروري، عند وجود حلول أكثر كفاءة. ستتناول هذه المدونة السيناريوهات الأكثر شيوعًا التي تحدث فيها عمليات قفل التنشيط المفرطة وتوصياتنا لتحسين عمليات قفل التنشيط. لقد شهدنا بالفعل نجاحًا ملموسًا من شركاء مثل نعيق، الذين استفادوا من هذه التوصيات لتحسين سلوكهم في الخلفية.
استخدام الخدمة الأمامية مقابل أقفال التنشيط الجزئية
لقد رأينا في كثير من الأحيان المطورين يكافحون من أجل فهم الفرق بين مفهومين عند تنفيذ التنفيذ في الخلفية: الخدمة الأمامية وأقفال التنشيط الجزئية.
الخدمة الأمامية عبارة عن واجهة برمجة تطبيقات لدورة الحياة تشير إلى النظام بأن التطبيق يقوم بعمل يمكن للمستخدم إدراكه ولا يجب إيقافه لاستعادة الذاكرة، ولكنه لا يمنع وحدة المعالجة المركزية تلقائيًا من النوم عند إيقاف تشغيل الشاشة. في المقابل، فإن قفل التنشيط الجزئي هو آلية مصممة خصيصًا للحفاظ على تشغيل وحدة المعالجة المركزية حتى أثناء إيقاف تشغيل الشاشة.
في حين أن الخدمة الأمامية غالبًا ما تكون ضرورية لمواصلة إجراء المستخدم، فإن الحصول اليدوي على قفل التنشيط الجزئي ضروري فقط بالتزامن مع الخدمة الأمامية طوال مدة نشاط وحدة المعالجة المركزية. بالإضافة إلى ذلك، لا تحتاج إلى استخدام قفل التنشيط إذا كنت تستخدم بالفعل واجهة برمجة التطبيقات (API) التي تبقي الجهاز نشطًا.
الرجوع إلى الرسم البياني في اختر واجهة برمجة التطبيقات المناسبة لإبقاء الجهاز نشطًا للتأكد من أن لديك فهمًا قويًا للأداة التي يجب استخدامها لتجنب الحصول على قفل التنشيط في السيناريوهات التي لا يكون فيها ذلك ضروريًا.
مكتبات الطرف الثالث تحصل على أقفال التنبيه
من الشائع أن يكتشف التطبيق أنه تم وضع علامة عليه بسبب عمليات قفل التنشيط المفرطة التي تحتفظ بها حزمة SDK أو واجهة برمجة تطبيقات النظام التابعة لجهة خارجية والتي تعمل نيابة عنه. لتحديد عمليات قفل التنشيط هذه وحلها، نوصي باتباع الخطوات التالية:
-
التحقق من مؤشرات Android الحيوية: ابحث عن الاسم الدقيق لقفل التنبيه المخالف في ملف لوحة القيادة لأقفال التنشيط الجزئية المفرطة. قم بالإشارة إلى هذا الاسم مع تحديد أقفال التنبيه التي تم إنشاؤها بواسطة واجهات برمجة التطبيقات الأخرى إرشادات لمعرفة ما إذا تم إنشاؤه بواسطة واجهة برمجة تطبيقات نظام معروفة أو مكتبة Jetpack. إذا كان الأمر كذلك، فقد تحتاج إلى تحسين استخدامك لواجهة برمجة التطبيقات (API) ويمكنك الرجوع إلى الإرشادات الموصى بها.
-
التقاط تتبع النظام: إذا لم يكن من الممكن التعرف على قفل التنشيط بسهولة، فأعد إنشاء مشكلة قفل التنشيط محليًا باستخدام تتبع النظام وافحصه باستخدام واجهة مستخدم Perfetto. يمكنك معرفة المزيد حول كيفية القيام بذلك في تصحيح أخطاء الأنواع الأخرى من أقفال التنشيط المفرطة قسم من هذا بلوق وظيفة.
-
تقييم البدائل: إذا كانت مكتبة تابعة لجهة خارجية غير فعالة هي المسؤولة ولا يمكن تهيئتها لاحترام عمر البطارية، ففكر في إبلاغ المشكلة مع مالكي SDK، أو العثور على SDK بديل أو بناء الوظيفة داخليًا.
فيما يلي تفاصيل لبعض حالات الاستخدام المحددة التي قمنا بمراجعتها، بالإضافة إلى المسار الموصى به لتحسين تنفيذ قفل التنشيط.
التحميل أو التنزيل الذي يبدأه المستخدم
أمثلة لحالات الاستخدام:
كيفية تقليل عمليات قفل التنشيط:
-
لا تحصل على قفل تنشيط يدوي. بدلاً من ذلك، استخدم واجهة برمجة تطبيقات نقل البيانات التي يبدأها المستخدم (UIDT).. هذا هو المسار المخصص لمهام نقل البيانات طويلة المدى التي يبدأها المستخدم، وهو معفى من حسابات قفل التنشيط المفرطة.
مزامنة الخلفية لمرة واحدة أو دورية
أمثلة لحالات الاستخدام:
كيفية تقليل عمليات قفل التنشيط:
-
لا تحصل على قفل تنشيط يدوي. يستخدم WorkManager تم تكوينه للعمل لمرة واحدة أو دورية. WorkManager يحترم صحة النظام من خلال تجميع المهام وله فترة دورية لا تقل عن 15 دقيقة، وهو ما يكفي بشكل عام لتحديثات الخلفية.
- إذا قمت بتحديد أقفال التنبيه التي تم إنشاؤها بواسطة WorkManager أو JobScheduler مع استخدام قفل التنشيط العالي، قد يكون السبب هو أنك أخطأت في تكوين العامل الخاص بك بحيث لا يكتمل في سيناريوهات معينة. يعتبر تحليل أسباب توقف العامل، خاصة إذا كنت ترى حدوثًا مرتفعًا لـ STOP_REASON_TIMEOUT.
workManager.getWorkInfoByIdFlow(syncWorker.id)
.collect { workInfo ->
if (workInfo != null) {
val stopReason = workInfo.stopReason
logStopReason(syncWorker.id, stopReason)
}
}
-
بالإضافة إلى تسجيل أسباب توقف العامل، راجع وثائقنا حول تصحيح أخطاء العاملين لديك. أيضا، النظر في جمع وتحليل آثار النظام لفهم متى يتم الحصول على أقفال التنبيه وإصدارها.
- وأخيرا، تحقق من موقعنا دراسة حالة مع WHOOP، حيث تمكنوا من اكتشاف مشكلة تتعلق بتكوين العاملين لديهم وتقليل تأثير قفل التنشيط بشكل كبير.
الاتصالات بلوتوث
أمثلة لحالات الاستخدام:
-
يطالب تطبيق الجهاز المرافق المستخدم بإقران جهاز Bluetooth الخارجي الخاص به.
-
يستمع تطبيق الجهاز المصاحب لأحداث الأجهزة على جهاز خارجي ويلاحظ المستخدم التغيير المرئي في الإشعارات.
-
يبدأ مستخدم تطبيق الجهاز المرافق عملية نقل الملفات بين الهاتف المحمول وجهاز البلوتوث.
-
يقوم تطبيق الجهاز المرافق بإجراء تحديثات البرامج الثابتة من حين لآخر لجهاز خارجي عبر البلوتوث.
كيفية تقليل عمليات قفل التنشيط:
-
يستخدم إقران الجهاز المرافق لإقران أجهزة Bluetooth لتجنب الحصول على قفل تنشيط يدوي أثناء إقران Bluetooth.
-
استشر التواصل في الخلفية إرشادات لفهم كيفية إجراء اتصال Bluetooth في الخلفية.
-
استخدام WorkManager غالبًا ما يكون ذلك كافيًا إذا لم يكن هناك تأثير للمستخدم على الاتصال المتأخر. إذا كان قفل التنشيط اليدوي ضروريًا، فاحتفظ بقفل التنشيط فقط طوال مدة نشاط Bluetooth أو معالجة بيانات النشاط.
تتبع الموقع
أمثلة لحالات الاستخدام:
-
تطبيقات اللياقة البدنية التي تخزن بيانات الموقع مؤقتًا لتحميلها لاحقًا مثل رسم مسارات الجري
-
تطبيقات توصيل الطعام التي تسحب بيانات الموقع بتردد عالٍ لتحديث تقدم التسليم في إشعار أو واجهة مستخدم لعنصر واجهة المستخدم.
كيفية تقليل عمليات قفل التنشيط:
-
راجع إرشاداتنا ل تحسين استخدام الموقع. فكر في تنفيذ المهلات، أو الاستفادة من تجميع طلبات الموقع، أو استخدام تحديثات الموقع السلبية لضمان كفاءة البطارية.
-
متى طلب تحديثات الموقع باستخدام واجهات برمجة تطبيقات FusedLocationProvider أو LocationManager، يقوم النظام تلقائيًا بتشغيل تنبيه الجهاز أثناء رد اتصال حدث الموقع. يتم استثناء قفل التنشيط المختصر هذا، والذي يُدار بواسطة النظام، من حسابات قفل التنشيط الجزئي المفرط.
- تجنب الحصول على قفل تنشيط منفصل ومستمر للتخزين المؤقت لبيانات الموقع، لأن هذا زائد عن الحاجة. بدلاً من ذلك، احتفظ بأحداث الموقع في الذاكرة أو التخزين المحلي والرافعة المالية WorkManager لمعالجتها على فترات دورية.
override fun onCreate(savedInstanceState: Bundle?) { locationCallback = object : LocationCallback() { override fun onLocationResult(locationResult: LocationResult?) { locationResult ?: return // System wakes up CPU for short duration for (location in locationResult.locations){ // Store data in memory to process at another time } } } }
مراقبة أجهزة الاستشعار عالية التردد
أمثلة لحالات الاستخدام:
-
تطبيقات عداد الخطى التي تجمع الخطوات أو المسافة المقطوعة بشكل سلبي.
-
تطبيقات الأمان التي تراقب مستشعرات الجهاز للتغيرات السريعة في الوقت الفعلي، لتوفير ميزات مثل اكتشاف الأعطال أو اكتشاف السقوط.
كيفية تقليل عمليات قفل التنشيط:
-
في حالة استخدام SensorManager، قم بتقليل الاستخدام إلى فترات زمنية دورية وفقط عندما يمنح المستخدم حق الوصول بشكل صريح من خلال تفاعل واجهة المستخدم. يمكن أن تؤدي مراقبة المستشعر عالي التردد إلى استنزاف البطارية بشكل كبير بسبب عدد عمليات التنبيه والمعالجة التي تحدث لوحدة المعالجة المركزية.
-
إذا كنت تتتبع عدد الخطوات أو المسافة المقطوعة، بدلاً من استخدام SensorManager، فاستخدم الرافعة المالية تسجيل API أو النظر في الاستفادة اتصال الصحة للوصول إلى عدد خطوات الجهاز التاريخية والمجمعة لالتقاط البيانات بطريقة فعالة للبطارية.
-
إذا كنت تقوم بتسجيل جهاز استشعار مع SensorManager، حدد أ maxReportLatencyUs من 30 ثانية أو أكثر للاستفادة منها تجميع أجهزة الاستشعار لتقليل تكرار مقاطعات وحدة المعالجة المركزية. عندما يتم إيقاظ الجهاز لاحقًا بواسطة مشغل آخر مثل تفاعل المستخدم، أو استرداد الموقع، أو مهمة مجدولة، سيقوم النظام على الفور بإرسال بيانات المستشعر المخزنة مؤقتًا.
val accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) sensorManager.registerListener(this, accelerometer, samplingPeriodUs, // How often to sample data maxReportLatencyUs // Key for sensor batching )
-
إذا كان تطبيقك يتطلب بيانات الموقع وأجهزة الاستشعار، فقم بمزامنة استرجاع الأحداث ومعالجتها. من خلال تحميل قراءات المستشعر على قفل التنشيط القصير الذي يحتفظ به النظام لتحديثات الموقع، فإنك تتجنب الحاجة إلى قفل التنشيط لإبقاء وحدة المعالجة المركزية نشطة. استخدم عاملاً أو قفل تنبيه قصير المدة للتعامل مع تحميل هذه البيانات المجمعة ومعالجتها.
المراسلة عن بعد
أمثلة لحالات الاستخدام:
-
التطبيقات المصاحبة لمراقبة الفيديو أو الصوت والتي تحتاج إلى مراقبة الأحداث التي تحدث على جهاز خارجي متصل باستخدام شبكة محلية.
-
تطبيقات المراسلة التي تحافظ على اتصال مقبس الشبكة مع متغير سطح المكتب.
كيفية تقليل عمليات قفل التنشيط:
-
إذا كان من الممكن معالجة أحداث الشبكة من جانب الخادم، فاستخدم إف سي إم لتلقي معلومات عن العميل. يمكنك اختيار جدولة عامل مستعجل إذا كانت هناك حاجة إلى معالجة إضافية لبيانات FCM.
-
إذا كان يجب معالجة الأحداث من جانب العميل عبر اتصال مأخذ توصيل، فلن تكون هناك حاجة إلى قفل التنبيه للاستماع إلى مقاطعات الأحداث. عندما تصل حزم البيانات إلى شبكة Wi-Fi أو الراديو الخلوي، تقوم أجهزة الراديو بتشغيل مقاطعة الأجهزة على شكل قفل تنشيط kernel. يمكنك بعد ذلك اختيار جدولة عامل أو الحصول على قفل التنبيه لمعالجة البيانات.
- على سبيل المثال، إذا كنت تستخدم شبكة ktor للاستماع إلى حزم البيانات الموجودة على مقبس الشبكة، يجب عليك الحصول على قفل التنبيه فقط عندما يتم تسليم الحزم إلى العميل وتحتاج إلى معالجتها.
val readChannel = socket.openReadChannel() while (!readChannel.isClosedForRead) { // CPU can safely sleep here while waiting for the next packet val packet = readChannel.readRemaining(1024) if (!packet.isEmpty) { // Data Arrived: The system woke the CPU and we should keep it awake via manual wake lock (urgent) or scheduling a worker (non-urgent) performWorkWithWakeLock { val data = packet.readBytes() // Additional logic to process data packets } } }

