بهترین شیوه های wake lock را دنبال کنید

استفاده از قفل بیدارباش می‌تواند عملکرد دستگاه را مختل کند. اگر نیاز به استفاده از قفل بیدارباش دارید، انجام صحیح آن بسیار مهم است. این سند برخی از بهترین شیوه‌ها را پوشش می‌دهد که می‌تواند به شما در جلوگیری از مشکلات رایج قفل بیدارباش کمک کند.

قفل بیدارباش را به درستی نامگذاری کنید

توصیه می‌کنیم نام بسته، کلاس یا متد خود را در تگ wakelock قرار دهید. به این ترتیب، اگر خطایی رخ دهد، پیدا کردن مکانی در کد منبع که قفل بیداری در آن ایجاد شده است، آسان‌تر خواهد بود. در اینجا چند نکته اضافی وجود دارد:

  • هرگونه اطلاعات شناسایی شخصی (PII) را در نام، مانند آدرس ایمیل، حذف کنید. اگر دستگاه PII را در برچسب قفل بیداری تشخیص دهد، به جای برچسبی که شما مشخص کرده‌اید، _UNKNOWN را ثبت می‌کند.
  • نام کلاس یا متد را به صورت برنامه‌نویسی شده، مثلاً با فراخوانی getName() دریافت نکنید. اگر سعی کنید نام را به صورت برنامه‌نویسی شده دریافت کنید، ممکن است توسط ابزارهایی مانند Proguard مبهم‌سازی شود. در عوض از یک رشته‌ی کدگذاری شده‌ی ثابت استفاده کنید.
  • برای برچسب‌های قفل بیداری، شمارنده یا شناسه‌های منحصر به فرد اضافه نکنید. کدی که قفل بیداری ایجاد می‌کند باید هر بار که اجرا می‌شود از برچسب یکسانی استفاده کند. این روش به سیستم امکان می‌دهد تا میزان استفاده از قفل بیداری هر روش را تجمیع کند.

مطمئن شوید که برنامه شما در پیش‌زمینه قابل مشاهده است

در حالی که قفل بیدارباش فعال است، دستگاه از برق استفاده می‌کند. کاربر دستگاه باید از این موضوع آگاه باشد. به همین دلیل، اگر از قفل بیدارباش استفاده می‌کنید، باید اعلانی را به کاربر نمایش دهید. در عمل، این بدان معناست که باید قفل بیدارباش را در یک سرویس پیش‌زمینه دریافت و نگه دارید. سرویس‌های پیش‌زمینه برای نمایش اعلان مورد نیاز هستند.

اگر یک سرویس پیش‌زمینه انتخاب مناسبی برای برنامه شما نیست، احتمالاً نباید از قفل بیدارباش نیز استفاده کنید. برای روش‌های دیگر انجام کار در حالی که برنامه شما در پیش‌زمینه نیست، به مستندات Choose the right API to keep the device wake lock مراجعه کنید.

منطق را ساده نگه دارید

مطمئن شوید که منطق دریافت و آزادسازی قفل‌های بیداری تا حد امکان ساده باشد. وقتی منطق قفل بیداری شما به ماشین‌های حالت پیچیده، وقفه‌های زمانی، مجموعه‌های اجراکننده یا رویدادهای فراخوانی مجدد گره خورده باشد، هرگونه اشکال ظریف در آن منطق می‌تواند باعث شود قفل بیداری بیش از حد انتظار نگه داشته شود. تشخیص و اشکال‌زدایی این اشکالات دشوار است.

بررسی کنید که قفل بیدارباش همیشه آزاد باشد

اگر از قفل بیداری استفاده می‌کنید، باید مطمئن شوید که هر قفل بیداری که به دست می‌آورید به درستی آزاد می‌شود. این کار همیشه به آن سادگی که به نظر می‌رسد نیست. برای مثال، کد زیر مشکل دارد:

کاتلین

@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();
    }
}