WakeLock: چیست، انواع و مدیریت قفل خواب

نویسنده: IT Sectr منتشر شده: 2026-03-28 زمان مطالعه: 9 دقیقه

WakeLock مکانیزمی در اندروید است که از انتقال دستگاه به حالت خواب جلوگیری می‌کند و پردازنده یا صفحه نمایش را در حالت فعال نگه می‌دارد. وظایف پس‌زمینه مانند دانلود فایل‌ها، پخش صدا یا ضبط داده‌ها برای اجرای تضمینی بدون وقفه به WakeLock نیاز دارند. طبق مشخصات Android Developers, 2025، استفاده نادرست از WakeLock منجر به تخلیه سریع باتری می‌شود و می‌تواند باعث مسدود شدن برنامه در Google Play شود.

نکات اصلی

  • WakeLock — قفل خواب، نگه‌دارنده دستگاه در حالت فعال
  • انواع — PARTIAL_WAKE_LOCK، FULL_WAKE_LOCK، SCREEN_DIM_WAKE_LOCK و موارد دیگر
  • مجوز — WAKE_LOCK در مانیفست الزامی است اما در runtime درخواست نمی‌شود
  • خطرات — WakeLock آزاد نشده باتری را تخلیه کرده و تجربه کاربری را بدتر می‌کند
  • جایگزین‌ها — WorkManager، Foreground Service، JobScheduler نیاز به WakeLock را کاهش می‌دهند

WakeLock چیست

WakeLock یک قفل سیستمی است که اندروید را از انتقال دستگاه به حالت مصرف انرژی پایین منع می‌کند. معمولاً اندروید پس از چند ثانیه عدم فعالیت کاربر، صفحه را خاموش کرده و پردازنده را به حالت خواب عمیق (deep sleep) می‌برد، که در آن نخ‌های پس‌زمینه متوقف می‌شوند. WakeLock از این انتقال جلوگیری می‌کند و CPU را در حالت فعال نگه می‌دارد.

مکانیزم WakeLock از طریق سرویس سیستمی PowerManager مدیریت می‌شود که از طریق متد getSystemService(Context.POWER_SERVICE) قابل دسترسی است. توسعه‌دهنده یک شی WakeLock با مشخص کردن نوع قفل ایجاد می‌کند و باید پس از اتمام کار آن را آزاد کند، در غیر این صورت باتری دستگاه به سرعت تخلیه می‌شود. سیستم WakeLock را به طور خودکار آزاد نمی‌کند — این مسئولیت برنامه است.

با هر نسخه اصلی اندروید، گوگل کنترل بر WakeLock را سخت‌تر می‌کند. از اندروید 9 (API 28) به بعد، برنامه در پس‌زمینه بدون دلیل موجه نمی‌تواند WakeLock دریافت کند و سیستم برنامه‌هایی که از قفل‌ها سوءاستفاده می‌کنند را ردیابی کرده و می‌تواند آنها را به زور آزاد کند. در اندروید 12+ محدودیت‌های اضافی برای دسترسی به PowerManager برای برنامه‌های پس‌زمینه اعمال شده است.

چه زمانی WakeLock لازم است

WakeLock در سناریوهایی مورد نیاز است که وظیفه نمی‌تواند با انتقال دستگاه به خواب قطع شود: دانلود فایل بزرگ از طریق اتصال ناپایدار، ضبط ویدئو، انجام محاسبات طولانی بدون مشارکت کاربر. بدون قفل خواب، پردازنده به خواب عمیق می‌رود، تمام نخ‌ها (threads) منجمد می‌شوند و وظیفه ناتمام می‌ماند.

با این حال، گوگل به شدت توصیه می‌کند که استفاده از WakeLock را به حداقل برسانید. در بیشتر موارد، همان وظیفه را می‌توان با Foreground Service با اعلان، WorkManager یا JobScheduler حل کرد. این مکانیزم‌ها وضعیت باتری و شبکه را در نظر می‌گیرند که عمر باتری دستگاه را افزایش می‌دهد.

WakeLock چگونه کار می‌کند

WakeLock از طریق سرویس سیستمی PowerManager که وضعیت تغذیه دستگاه را مدیریت می‌کند کار می‌کند. وقتی برنامه از طریق powerManager.newWakeLock() قفل درخواست می‌کند، سیستم سطح فعالیت CPU را افزایش داده و از انتقال به خواب عمیق جلوگیری می‌کند. پس از فراخوانی wakeLock.release() سیستم به حالت عادی صرفه‌جویی انرژی بازمی‌گردد.

درک این نکته مهم است که WakeLock از همه حالت‌های صرفه‌جویی انرژی جلوگیری نمی‌کند. Doze Mode (حالت خواب اندروید 6+) ممکن است در فازهای خاصی WakeLock را نادیده بگیرد — برنامه با WakeLock نگه‌داشته شده در پنجره‌های سرویس Doze به شبکه دسترسی نخواهد داشت. این بدان معناست که حتی WakeLock فعال نیز اجرای عملیات شبکه را در طول فاز دوم Doze تضمین نمی‌کند.

هر WakeLock با PowerManager.WakeLock در سمت فریم‌ورک مرتبط است. سیستم شمارش قفل‌های فعال را در سطح فرآیند حفظ می‌کند: اگر یک فرآیند چندین WakeLock را نگه دارد، آنها جمع می‌شوند و آزادسازی فقط پس از فراخوانی release() برای هر قفل انجام می‌شود. اندروید همچنین از wake lock timeouts پشتیبانی می‌کند — آزادسازی خودکار پس از بازه زمانی مشخص. با این حال، تکیه بر timeout توصیه نمی‌شود: وظیفه ممکن است زودتر تمام شود و زمان اضافی نگهداشت عمر باتری را کاهش می‌دهد.

WakeLock و رویدادهای سیستمی

هنگام انتقال دستگاه به حالت خواب (دکمه پاور)، اندروید به زور تمام SCREEN_DIM_WAKE_LOCK و SCREEN_BRIGHT_WAKE_LOCK را آزاد می‌کند اما PARTIAL_WAKE_LOCK را حفظ می‌کند. این بدان معناست که قفل صفحه نمی‌تواند دستگاه را از خاموش کردن نمایشگر بازدارد — فقط PARTIAL_WAKE_LOCK می‌تواند پس از فشار دکمه پاور به کار ادامه دهد.

انواع WakeLock در اندروید

در اندروید چندین نوع WakeLock وجود دارد که هر کدام اجزای خاصی از دستگاه را مدیریت می‌کنند. انتخاب نوع تعیین می‌کند که کدام اجزای سخت‌افزاری پس از قفل فعال می‌مانند. انتخاب نادرست نوع به دلیل فعال شدن ماژول‌های غیرضروری منجر به مصرف بیش از حد انرژی می‌شود.

نوعCPUصفحهصفحه کلیدزمان استفاده
PARTIAL_WAKE_LOCKروشنخاموشخاموشدانلود فایل‌ها، محاسبات
SCREEN_DIM_WAKE_LOCKروشنکم نورخاموشپخش‌کننده ویدئو، ارائه
SCREEN_BRIGHT_WAKE_LOCKروشنروشنخاموشبازی‌ها (منسوخ)
FULL_WAKE_LOCKروشنروشنروشنمنسوخ (deprecated)

PARTIAL_WAKE_LOCK — نوع اصلی

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

انواع منسوخ (deprecated)

SCREEN_DIM_WAKE_LOCK، SCREEN_BRIGHT_WAKE_LOCK و FULL_WAKE_LOCK از اندروید 7 (API 24) به عنوان منسوخ علامت‌گذاری شده‌اند. آنها صفحه را روشن نگه می‌دارند که منجر به مصرف قابل توجه باتری می‌شود. گوگل به جای آنها استفاده از FLAG_KEEP_SCREEN_ON را از طریق Activity.getWindow().addFlags() توصیه می‌کند — این پرچم فقط با Activity فعال کار می‌کند و به مجوز WAKE_LOCK نیاز ندارد و سیستم به طور خودکار زمان نگهداشت صفحه را مدیریت می‌کند.

WakeLock و مصرف انرژی

WakeLock یکی از اصلی‌ترین «مصرف‌کنندگان» باتری در اندروید است. هر ثانیه نگهداشتن قفل خواب انرژی اضافی مصرف می‌کند زیرا پردازنده نمی‌تواند به حالت کم مصرف C-state منتقل شود. تحقیقات Google Power Dashboard نشان می‌دهد که برنامه‌هایی با WakeLock به درستی آزاد نشده می‌توانند مصرف انرژی دستگاه را در حالت آماده به کار 30–50% افزایش دهند.

سیستم برنامه‌هایی که از WakeLock سوءاستفاده می‌کنند را از طریق مؤلفه Battery Historian ردیابی می‌کند. توسعه‌دهنده می‌تواند مشخصات مصرف انرژی را تحلیل کرده و «نشت» قفل‌ها — موقعیت‌هایی که WakeLock ایجاد شده اما آزاد نشده — را شناسایی کند. Google Play Console آمار WakeLock را برای برنامه‌های منتشر شده نشان می‌دهد و زمان نگهداشت طولانی می‌تواند باعث نظرات منفی شود.

Doze Mode و App Standby به طور اضافی کار WakeLock را محدود می‌کنند. در فاز اول Doze (Light Doze) سیستم WakeLock را در پنجره‌های سرویس کوتاه مجاز می‌داند. در فاز دوم (Deep Doze) WakeLock با سایر قفل‌ها ترکیب شده و در یک پنجره مشترک اجرا می‌شود. اگر برنامه بیش از 10 دقیقه بدون تعامل کاربر WakeLock را نگه دارد، سیستم می‌تواند آن را به زور آزاد کرده و برنامه را در لیست سیاه بهینه‌سازی باتری قرار دهد.

  • Battery Historian — ابزاری برای تحلیل مصرف انرژی و نشت WakeLock
  • Doze Mode — WakeLock را در پنجره‌های سرویس محدود کرده و قفل‌ها را ترکیب می‌کند
  • Google Play Console — آمار WakeLock را برای برنامه‌های منتشر شده نمایش می‌دهد
  • لیست سیاه — برنامه ممکن است توسط سیستم به عنوان پرمصرف علامت‌گذاری شود

بهترین روش‌های استفاده

استفاده صحیح از WakeLock تعادلی بین نیاز به انجام وظیفه و مراقبت از باتری دستگاه است. گوگل توصیه می‌کند چند اصل را رعایت کنید: همیشه WakeLock را در finally یا از طریق acquire(timeout) آزاد کنید، از حداقل نوع قفل لازم استفاده کنید و از نگهداشت طولانی مدت بدون ضرورت اجتناب کنید.

قانون آزادسازی

WakeLock باید در همان بلوک کدی که ایجاد شده آزاد شود. برای تضمین آزادسازی در هنگام استثناها از ساختار try-finally یا بلوک use در Kotlin استفاده می‌شود. در اندروید 10+ اگر WakeLock بیش از 60 ثانیه نگه داشته شود، سیستم هشداری در logcat نمایش می‌دهد: "WakeLock held for more than 60 seconds" — این سیگنالی از نشت احتمالی است.

مهلت زمانی در اخذ

متد acquire(long timeout) به طور خودکار WakeLock را پس از زمان مشخص شده به میلی‌ثانیه آزاد می‌کند. این بیمه‌ای برای مواردی است که کد آزادسازی به دلیل استثنا یا باگ اجرا نشود. توصیه می‌شود همیشه timeout برابر با حداکثر زمان مورد انتظار اجرای وظیفه به علاوه 10–20% ذخیره تعیین کنید.

بررسی وجود قفل

قبل از فراخوانی release() باید بررسی کنید که آیا WakeLock در حال حاضر نگه داشته شده است. فراخوانی مجدد release() بدون acquire() قبلی باعث RuntimeException: WakeLock under-locked می‌شود. توصیه می‌شود پرچم وضعیت (isHeld) را ذخیره کرده و قبل از آزادسازی wakeLock.isHeld() را بررسی کنید.

استفاده از WakeLock در Kotlin

بیایید ایجاد و آزادسازی صحیح WakeLock در Kotlin را بررسی کنیم. مثال دانلود ناهمگام داده با نگهداشتن PARTIAL_WAKE_LOCK، آزادسازی تضمینی در بلوک try-finally و تعیین timeout برای محافظت در برابر نشت را نشان می‌دهد. سرویس از CoroutineScope با调度‌کننده IO برای اجرای وظیفه پس‌زمینه استفاده می‌کند.

kotlin
class DownloadService : Service() {

    private lateinit var wakeLock: PowerManager.WakeLock
    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    override fun onCreate() {
        super.onCreate()
        val powerManager = getSystemService(Context.POWER_SERVICE) as PowerManager
        wakeLock = powerManager.newWakeLock(
            PowerManager.PARTIAL_WAKE_LOCK,
            "download:wakelock"
        )
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        wakeLock.acquire(60000)
        scope.launch {
            try {
                downloadFile()
            } finally {
                if (wakeLock.isHeld()) {
                    wakeLock.release()
                }
            }
        }
        return START_NOT_STICKY
    }

    private suspend fun downloadFile() {
        // شبیه‌سازی دانلود فایل
        delay(30000)
    }

    override fun onDestroy() {
        super.onDestroy()
        scope.cancel()
        if (wakeLock.isHeld()) {
            wakeLock.release()
        }
    }

    override fun onBind(intent: Intent): IBinder? = null
}

اعلام مجوز در مانیفست

برای استفاده از WakeLock باید مجوز را در AndroidManifest.xml اضافه کنید. مجوز WAKE_LOCK یک مجوز عادی (normal) است — نیازی به درخواست runtime از کاربر ندارد و هنگام نصب برنامه به طور خودکار اعطا می‌شود. با این حال، Google Play ممکن است انتشار را رد کند اگر برنامه سناریوی واضحی برای استفاده از WakeLock نداشته باشد.

xml
<uses-permission
    android:name="android.permission.WAKE_LOCK" />

<uses-permission
    android:name="android.permission.DEVICE_POWER" />

جایگزین‌های WakeLock

WakeLock یک مکانیزم سطح پایین است و گوگل توصیه می‌کند در صورت امکان آن را با APIهای مدرن‌تر جایگزین کنید. جایگزین اصلی Foreground Service با اعلان است که به طور خودکار قفل CPU را در طول مدت سرویس نگه می‌دارد. سیستم خود WakeLock را برای Foreground Service مدیریت می‌کند و توسعه‌دهنده را از نیاز به اخذ و آزادسازی صریح بی‌نیاز می‌کند.

WorkManager دومین ابزار مهم برای وظایف پس‌زمینه است. اجرای کار را حتی در هنگام انتقال دستگاه به Doze و پس از راه‌اندازی مجدد تضمین می‌کند. WorkManager از نگهدارنده قفل (hold lock) در داخل خود پشتیبانی می‌کند — توسعه‌دهنده نیازی به کار مستقیم با PowerManager ندارد. وظیفه در پنجره سرویس Doze با مدیریت خودکار قفل خواب اجرا می‌شود.

برای وظایف منظم که زمان دقیق نیاز دارند، از AlarmManager با setAndAllowWhileIdle() استفاده می‌شود که می‌تواند دستگاه را از Doze بیدار کند. با این حال AlarmManager فقط برای عملیات کوتاه مناسب است — برای نگهداشت طولانی مدت WakeLock طراحی نشده است. اگر وظیفه بیش از 10 ثانیه طول بکشد، باید AlarmManager را با BroadcastReceiver که Foreground Service را راه‌اندازی می‌کند ترکیب کنید.

  • Foreground Service — مدیریت خودکار WakeLock با اعلان
  • WorkManager — اجرای تضمینی با در نظر گرفتن Doze و راه‌اندازی مجدد
  • JobScheduler — برنامه‌ریزی با در نظر گرفتن شبکه، شارژ و بیکاری
  • AlarmManager — بیدار کردن دستگاه برای وظایف کوتاه طبق زمان‌بندی

سوالات متداول

WakeLock در اندروید چیست؟

WakeLock یک قفل سیستمی است که از انتقال دستگاه اندروید به حالت خواب جلوگیری می‌کند. پردازنده یا صفحه را در حالت فعال نگه می‌دارد و به وظایف پس‌زمینه (دانلود، محاسبات) اجازه می‌دهد بدون وقفه اجرا شوند. از طریق سرویس سیستمی PowerManager مدیریت می‌شود.

چه انواع WakeLock وجود دارد؟

انواع اصلی: PARTIAL_WAKE_LOCK (CPU فعال، صفحه خاموش) — توصیه می‌شود؛ SCREEN_DIM_WAKE_LOCK (CPU + صفحه کم نور)؛ SCREEN_BRIGHT_WAKE_LOCK (CPU + صفحه روشن). SCREEN_DIM، SCREEN_BRIGHT و FULL_WAKE_LOCK به عنوان منسوخ علامت‌گذاری شده و با FLAG_KEEP_SCREEN_ON جایگزین شده‌اند.

آیا برای WakeLock مجوز نیاز است؟

بله، در مانیفست باید android.permission.WAKE_LOCK اعلام شود. این یک مجوز عادی (normal permission) است که هنگام نصب به طور خودکار اعطا می‌شود — نیازی به درخواست در runtime نیست. بدون این مجوز، فراخوانی newWakeLock() null برمی‌گرداند یا SecurityException پرتاب می‌کند.

اگر WakeLock آزاد نشود چه اتفاقی می‌افتد؟

اگر release() فراخوانی نشود، دستگاه نمی‌تواند به حالت خواب برود. باتری به طور قابل توجهی سریع‌تر تخلیه می‌شود (تا 50% مصرف اضافی). سیستم نشت را در logcat ثبت می‌کند و Battery Historian زمان غیرعادی نگهداشت WakeLock را نشان می‌دهد که منجر به نظرات منفی کاربران می‌شود.

در برنامه‌های مدرن WakeLock را با چه چیزی جایگزین کنیم؟

برای وظایف طولانی از Foreground Service با اعلان استفاده کنید — سیستم خود WakeLock را مدیریت می‌کند. برای وظایف به تأخیر افتاده و تضمینی از WorkManager استفاده کنید که WakeLock را در داخل خود پشتیبانی می‌کند. برای وظایف کوتاه زمان‌بندی — AlarmManager.

خلاصه

  • WakeLock — قفل خواب، نگه‌دارنده CPU یا صفحه دستگاه اندروید در حالت فعال
  • PARTIAL_WAKE_LOCK — نوع اصلی برای وظایف پس‌زمینه؛ صفحه خاموش، CPU فعال می‌ماند
  • مجوز — WAKE_LOCK در مانیفست (normal permission، runtime لازم نیست)
  • نشت — WakeLock آزاد نشده باتری را 30–50% تخلیه می‌کند؛ در finally یا با timeout آزاد کنید
  • منسوخ — SCREEN_DIM، SCREEN_BRIGHT و FULL_WAKE_LOCK با FLAG_KEEP_SCREEN_ON جایگزین شده‌اند
  • Foreground Service — جایگزین با مدیریت خودکار WakeLock و اعلان
  • WorkManager — بهترین انتخاب برای وظایف پس‌زمینه تأخیری با اجرای تضمینی

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید