استفاده از قفل بیداری میتواند عملکرد دستگاه را مختل کند. اگر لازم است از قفل بیداری استفاده کنید، مهم است که این کار را بهدرستی انجام دهید. این سند برخیاز روالهای مطلوب را پوشش میدهد که میتواند به شما کمک کند از مشکلات رایج قفل بیداری اجتناب کنید.
نامگذاری صحیح قفل بیداری
توصیه میکنیم نام بسته، کلاس، یا روش خود را در برچسب wakelock بگنجانید. بهاینترتیب، اگر خطایی رخ دهد، پیدا کردن مکان ایجاد قفل بیداری در کد منبع آسانتر خواهد بود. در اینجا چند نکته دیگر آورده شده است:
- اطلاعات شناساننده شخصی (PII) را در نام وارد نکنید،
مثلاً نشانی ایمیل. اگر دستگاه اطلاعات شناساننده شخصی را در برچسب قفل بیداری شناسایی کند، بهجای برچسبی که مشخص کردهاید،
_UNKNOWNرا ثبت میکند. - نام کلاس یا روش را بهصورت برنامهنویسیشده دریافت نکنید، برای مثال با
فراخوانی
getName(). اگر سعی کنید نام را بهصورت برنامهنویسیشده دریافت کنید، ممکن است توسط ابزارهایی مانند Proguard مبهم شود. درعوض از رشته کدگذاریشده استفاده کنید. - به برچسبهای قفل بیداری، شمارنده یا شناسههای یکتا اضافه نکنید. کدی که قفل بیداری را ایجاد میکند باید هربار که اجرا میشود از همان برچسب استفاده کند. این کار به سیستم امکان میدهد مصرف قفل بیداری هر روش را تجمیع کند.
مطمئن شوید برنامهتان در پیشزمینه قابلمشاهده باشد
وقتی قفل بیداری فعال است، دستگاه از برق استفاده میکند. کاربر دستگاه باید بداند که این اتفاق درحال رخ دادن است. به همین دلیل، اگر از قفل بیداری استفاده میکنید، باید اعلانی به کاربر نشان دهید. در عمل، این یعنی باید قفل بیدارباش را در سرویس پیشزمینهای دریافت و حفظ کنید. سرویسهای پیشزمینهای برای نمایش اعلان لازم است.
اگر سرویس پیشزمینهای انتخاب مناسبی برای برنامهتان نیست، احتمالاً نباید از قفل بیداری هم استفاده کنید. برای روشهای دیگر انجام کار وقتی برنامهتان در پیشنما نیست، به سند انتخاب API مناسب برای بیدار نگه داشتن دستگاه مراجعه کنید.
منطق را ساده نگه دارید
مطمئن شوید منطق دریافت و رها کردن قفلهای بیداری تا حد امکان ساده باشد. وقتی منطق قفل بیداری شما به ماشینهای حالت پیچیده، زمانهای اتمام، استخرهای اجراکننده، یا رویدادهای بازگشت تماس گره خورده باشد، هر اشکال جزئی در آن منطق میتواند باعث شود قفل بیداری طولانیتر از حد انتظار نگه داشته شود. تشخیص و اشکالزدایی این اشکالات دشوار است.
بررسی کنید که قفل بیداری همیشه آزاد شود
اگر از قفل بیداری استفاده میکنید، باید مطمئن شوید که هر قفل بیداری که دریافت میکنید بهدرستی آزاد میشود. این کار همیشه به آن آسانی که بهنظر میرسد نیست. برای مثال، کد زیر مشکل دارد:
کاتلین
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
acquire()
doTheWork() // can potentially throw MyException
release() // does not run if an exception is thrown
}
}
جاوا
void doSomethingAndRelease() throws MyException {
wakeLock.acquire();
doTheWork(); // can potentially throw MyException
wakeLock.release(); // does not run if an exception is thrown
}
مشکل اینجا است که روش doTheWork() میتواند استثنای
MyException را ایجاد کند. اگر این اتفاق بیفتد، روش doSomethingAndRelease() استثنا را به بیرون منتشر میکند و هرگز به تماس release() نمیرسد. نتیجه این است که قفل بیداری بهدست میآید اما آزاد نمیشود، که بسیار بد است.
در کد اصلاحشده، doSomethingAndRelease() مطمئن میشود که قفل بیداری
حتی درصورت ایجاد استثنا آزاد میشود:
کاتلین
@Throws(MyException::class)
fun doSomethingAndRelease() {
wakeLock.apply {
try {
acquire()
doTheWork()
} finally {
release()
}
}
}
جاوا
void doSomethingAndRelease() throws MyException {
try {
wakeLock.acquire();
doTheWork();
} finally {
wakeLock.release();
}
}