حالت Doze یک حالت ذخیره انرژی اندروید است که در نسخه 6.0 Marshmallow معرفی شد و فعالیت پسزمینه برنامهها را در زمان بیکاری دستگاه به طور قابل توجهی محدود میکند. سیستم برنامهها را به حالت مصرف انرژی کاهشیافته منتقل میکند و درخواستهای شبکه، همگامسازی و JobScheduler را به تعویق میاندازد تا عمر باتری را افزایش دهد. بر اساس تحلیل Android Developers, 2025، حالت Doze امکان افزایش زمان آمادهبهکار دستگاه را تا 2–3 برابر بسته به مدل و نسخه سیستم عامل فراهم میکند.
نکات اصلی
حالت Doze یک مکانیزم داخلی ذخیره انرژی اندروید است که زمانی فعال میشود که دستگاه به شارژر متصل نیست، صفحه نمایش خاموش است و کاربر برای مدت مشخصی با دستگاه تعامل ندارد. هدف Doze به حداقل رساندن فعالیت پسزمینه برنامهها برای افزایش حداکثری عمر باتری در حالت آمادهبهکار است. سیستم JobScheduler، همگامسازی حسابها، AlarmManager و درخواستهای شبکه را به تعویق میاندازد.
این حالت در اندروید 6.0 Marshmallow (API 23) معرفی شد و در نسخههای بعدی به طور قابل توجهی بهبود یافت. در اندروید 7.0 Nougat فاز دوم (Light Doze) ظاهر شد که در هنگام حرکت دستگاه فعال میشود. اندروید 8.0 محدودیتهای اضافی روی سرویسهای پسزمینه که با Doze کار میکنند اعمال کرد. در اندروید 12+، Doze با سیستم مدیریت باتری بهروزرسانیشده که رفتار کاربر را تحلیل میکند، ادغام شد.
درک این نکته مهم است: حالت Doze برنامهها را به طور کامل غیرفعال نمیکند. آنها را به حالت وظایف بهتعویقافتاده منتقل میکند، اما فرآیندها را نمیکشد. Foreground Service با اعلان به کار خود ادامه میدهد، اعلانهای فشاری با اولویت بالا (FCM high-priority) تحویل داده میشوند و زنگها طبق برنامه فعال میشوند. Doze فقط بر عملیاتهای پسزمینهای تأثیر میگذارد که کاربر در حال حاضر نمیبیند و انتظار ندارد.
حالت Doze زمانی فعال میشود که همه شرایط برآورده شوند: صفحه نمایش بیش از 30 دقیقه خاموش باشد (فعالسازی اول)، دستگاه بیحرکت باشد (از شتابسنج استفاده میشود)، به شارژر متصل نباشد. اگر کاربر گوشی را بردارد یا شارژر را وصل کند، Doze بلافاصله غیرفعال میشود. در اندروید 7+، Light Doze حتی با حرکت دستگاه، پس از 5 دقیقه بیکاری فعال میشود.
حالت Doze فعالیت پسزمینه را از طریق سرویس سیستمی DeviceIdleController مدیریت میکند که وضعیت سنسورها، صفحه نمایش و شارژر را تحلیل میکند. وقتی همه شرایط فعالسازی برآورده شد، سیستم برنامهها را به حالت انتظار منتقل میکند و درخواستهای آنها را در پنجرههای سرویس گروهبندی میکند. در داخل این پنجرهها، همه وظایف بهتعویقافتاده — فراخوانیهای شبکه، همگامسازی، AlarmManager — به صورت دستهای اجرا میشوند.
PowerManager سیستمی کنترل میکند کدام برنامهها میتوانند از Doze خارج شوند. اعلانهای فشاری با اولویت بالا (FCM high-priority) میتوانند دستگاه را برای تحویل پیام بیدار کنند. همچنین سیستم Doze را برای برنامههایی که کاربر به Whitelist بهینهسازی باتری اضافه کرده است نادیده میگیرد. همه برنامههای دیگر باید منتظر پنجره سرویس بعدی باشند.
مدت زمان پنجرههای سرویس در Deep Doze به صورت نمایی افزایش مییابد: اولین پنجره بعد از 1 ساعت، دومین بعد از 2 ساعت، سومین بعد از 4 ساعت و به همین ترتیب تا حداکثر فاصله 12 ساعت. این بدان معناست که هرچه دستگاه بیشتر در Doze بماند، برنامهها کمتر میتوانند وظایف پسزمینه را انجام دهند — باتری به حداکثر میزان ممکن ذخیره میشود.
در حالت Doze، همه درخواستهای شبکه تا رسیدن پنجره سرویس متوقف میشوند. فقط پیامهای FCM high-priority (با برچسب «high_priority» در payload) و سیگنالهای AlarmManager با پرچمهای setAndAllowWhileIdle() یا setExactAndAllowWhileIdle() استثنا هستند. فراخوانیهای معمولی شبکه از طریق Retrofit، OkHttp یا Volley تا باز شدن پنجره اجرا نخواهند شد.
حالت Doze از دو فاز تشکیل شده است: Light Doze (خواب سبک) و Deep Doze (خواب عمیق). هر فاز محدودیتهای خاص خود را اعمال میکند و آستانههای فعالسازی متفاوتی دارد. درک تفاوت بین فازها برای برنامهنویسی که وظایف پسزمینه مقاوم در برابر حالت ذخیره انرژی را طراحی میکند، حیاتی است.
Light Doze پس از 5–30 دقیقه بیکاری دستگاه فعال میشود (صفحه خاموش، بدون حرکت). در این فاز، درخواستهای شبکه و همگامسازی متوقف میشوند، اما AlarmManager و JobScheduler با تأخیرهای جزئی به کار خود ادامه میدهند. برنامهها میتوانند با دریافت اعلان فشاری یا اتصال به شارژر از Light Doze خارج شوند. Light Doze به بیحرکتی کامل نیاز ندارد — دستگاه میتواند در حرکت باشد.
Deep Doze پس از 60–90 دقیقه بیکاری با دستگاه بیحرکت (شتابسنج حرکتی ثبت نمیکند) رخ میدهد. در Deep Doze، سیستم وظایف را به طور قابل توجهی تهاجمیتر به تعویق میاندازد: پنجرههای سرویس کمتر باز میشوند (با افزایش نمایی فاصله)، AlarmManager فقط با پرچمهای setAndAllowWhileIdle() فعال میشود و WakeLock در حالت عادی کار نمیکند. برنامههایی که در Whitelist نیستند عملاً فعالیت پسزمینه را کاملاً از دست میدهند.
| پارامتر | Light Doze | Deep Doze |
|---|---|---|
| زمان فعالسازی | 5–30 دقیقه | 60–90 دقیقه |
| نیاز به حرکت | نیاز نیست | بیحرکتی |
| فاصله پنجرهها | 10–60 دقیقه | 1–12 ساعت |
| AlarmManager | با تأخیر کار میکند | فقط withAllowWhileIdle |
| شبکه در پنجرهها | در دسترس | در دسترس |
حالت Doze چندین دسته محدودیت اعمال میکند که برنامهنویس باید هنگام طراحی برنامه در نظر بگیرد. نادیده گرفتن این محدودیتها منجر به عدم اجرای وظایف پسزمینه میشود و کاربر عملکرد نادرست برنامه را مشاهده میکند — عدم بهروزرسانی، پیامهای ارسالنشده، همگامسازی انجامنشده.
همه درخواستهای شبکه تا رسیدن پنجره سرویس مسدود میشوند. این شامل فراخوانیهای HTTP، اتصالات WebSocket، بارگیری فایلها میشود. استثنا — پیامهای FCM high-priority که از طریق کانال جداگانه Google Play Services عبور میکنند و به Doze وابسته نیستند. برای همگامسازی دادههای حیاتی، استفاده از WorkManager با سیاست NetworkType.CONNECTED توصیه میشود.
AlarmManager در Deep Doze همه زنگها را به جز آنهایی که با متدهای setAndAllowWhileIdle() و setExactAndAllowWhileIdle() ایجاد شدهاند به تعویق میاندازد. با این حال، حتی این متدها نیز محدودیت دارند — حداکثر 1 بار در 9 دقیقه برای هر برنامه. زنگهای دقیق setExact() در Deep Doze تضمینی برای فعال شدن در زمان مشخص ندارند.
WakeLock در حالت Doze به صورت غیراستاندارد کار میکند: سیستم قفل خواب را برای برنامههای خارج از Whitelist حفظ نمیکند. حتی اگر برنامه به درستی PARTIAL_WAKE_LOCK را گرفته باشد، با رسیدن Deep Doze سیستم میتواند آن را به زور آزاد کند. تنها راه تضمین اجرای وظیفه در Doze استفاده از Foreground Service با اعلان است.
Whitelist (لیست سفید) Doze مجموعهای از برنامههایی است که سیستم با حداقل محدودیتها اجازه فعالیت پسزمینه در حالت ذخیره انرژی را به آنها میدهد. کاربر میتواند برنامهها را به صورت دستی از طریق تنظیمات → باتری → بهینهسازی باتری اضافه کند. برنامههای سیستمی، لانچرها و سرویسهای Google Play Services به طور پیشفرض در Whitelist هستند.
برنامهنویس میتواند از طریق دیالوگ سیستمی با Intent ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS درخواست اضافه شدن به Whitelist را بدهد. برای این کار در مانیفست مجوز REQUEST_IGNORE_BATTERY_OPTIMIZATIONS مورد نیاز است. با این حال، گوگل توصیه میکند بدون دلیل موجه درخواست استثنا ندهید — برنامههایی که از این قابلیت سوءاستفاده میکنند در معرض رد شدن در Google Play هستند.
بدون Whitelist، برنامه میتواند از FCM high-priority برای بیدار کردن دستگاه از Doze استفاده کند. هر یک از این پیامها یک پنجره کوتاه (10–30 ثانیه) به برنامه میدهد تا وظیفه خود را انجام دهد. برای عملیاتهای طولانیتر، برنامه باید Foreground Service را راهاندازی کند که در پنجرههای سرویس Doze به کار ادامه میدهد. گوگل همچنین مکانیزم معافیت برای برخی انواع برنامهها را ارائه میدهد: برنامههای ناوبری، پزشکی، پیامرسان.
برای بررسی اینکه آیا برنامه در Whitelist بهینهسازی باتری قرار دارد، از متد powerManager.isIgnoringBatteryOptimizations() استفاده میشود. اگر متد false برگرداند، برنامه تابع همه محدودیتهای Doze است. اگر true — برنامه میتواند از Wakelock، AlarmManager و شبکه بدون محدودیت حتی در Deep Doze استفاده کند. با این حال، سوءاستفاده از این امتیاز منجر به نظرات بد کاربران خواهد شد.
تست رفتار برنامه در حالت Doze یک مرحله اجباری توسعه است، زیرا Doze میتواند عملکردهای پسزمینه را مختل کند. اندروید ابزارهای خط فرمان را از طریق ADB برای انتقال اجباری دستگاه به Light Doze و Deep Doze فراهم میکند. تست باید روی دستگاه فیزیکی یا شبیهساز با اندروید 6.0+ انجام شود.
برای ورود به Light Doze از دستور adb shell dumpsys deviceidle step light استفاده میشود. برای Deep Doze — adb shell dumpsys deviceidle step deep. دستور adb shell dumpsys deviceidle force-idle deep بلافاصله دستگاه را بدون انتظار برای تایماوت استاندارد به Deep Doze منتقل میکند. پس از تست، Doze با دستور adb shell dumpsys deviceidle unforce غیرفعال میشود.
# ورود اجباری به Light Doze
$ adb shell dumpsys deviceidle step light
# ورود اجباری به Deep Doze
$ adb shell dumpsys deviceidle step deep
# انتقال فوری به Deep Doze
$ adb shell dumpsys deviceidle force-idle deep
# خروج از Doze
$ adb shell dumpsys deviceidle unforce
# مشاهده وضعیت Doze
$ adb shell dumpsys deviceidle
پس از انتقال به حالت Doze، باید بررسی کرد: آیا درخواستهای شبکه کار میکنند (باید به تعویق بیفتند)، آیا AlarmManager فعال میشود، آیا پیامهای FCM تحویل داده میشوند، آیا وظایف WorkManager به درستی اجرا میشوند. WorkManager در Doze به کار خود ادامه میدهد: وظایف آن در پنجرههای سرویس اجرا میشوند. با این حال، اگر وظیفه نیاز به اجرای فوری دارد، باید setExpedited() مشخص شود یا از Foreground Service استفاده شود.
توسعه برنامهای مقاوم در برابر حالت Doze نیاز به بازنگری در رویکرد به وظایف پسزمینه دارد. گوگل توصیه میکند برنامه را طوری طراحی کنید که با هر محدودیت Doze به درستی کار کند، بدون اتکا به اجرای فوری عملیاتهای پسزمینه. اصل اساسی — استفاده از WorkManager برای همه وظایف پسزمینهای که میتوانند به تعویق بیفتند.
WorkManager API توصیهشده گوگل برای وظایف پسزمینه است، زیرا به طور خودکار با Doze سازگار میشود. WorkManager از JobScheduler (API 23+) یا AlarmManager + BroadcastReceiver در نسخههای قدیمی استفاده میکند. وظایف WorkManager در نزدیکترین پنجره سرویس Doze اجرا میشوند و در صورت نیاز — بلافاصله از طریق Expedited Work (Foreground Service در پشت صحنه).
اگر وظیفه قابل تعویق نیست (پخش رسانه، ناوبری، VoIP)، از Foreground Service با اعلان اجباری استفاده کنید. Foreground Service از Doze معافیت میگیرد: میتواند WakeLock را نگه دارد و درخواستهای شبکه را انجام دهد. با این حال، حتی Foreground Service نیز برای برخی انواع وظایف — مثلاً dataSync — تابع سیاست پنجرههای سرویس Deep Doze است.
برای تحویل پیامهایی که نیاز به توجه فوری دارند (تماس ورودی، اعلان فوری)، از پیامهای FCM high-priority استفاده کنید. چنین پیامهایی دستگاه را از Doze بیدار میکنند و یک پنجره کوتاه برای پردازش به برنامه میدهند. از high-priority برای اعلانهای معمولی استفاده نکنید — این منجر به تخلیه سریع باتری میشود و ممکن است توسط Google Play نقض سیاست تلقی شود.
سوالات متداول
حالت Doze یک حالت ذخیره انرژی اندروید 6+ است که وقتی دستگاه استفاده نمیشود (صفحه خاموش، بدون حرکت) فعالیت پسزمینه برنامهها را محدود میکند. سیستم درخواستهای شبکه، همگامسازی و JobScheduler را به تعویق میاندازد و آنها را برای صرفهجویی در باتری در پنجرههای سرویس گروهبندی میکند.
حالت Doze دو فاز دارد: Light Doze (خواب سبک) بعد از 5–30 دقیقه فعال میشود و به AlarmManager با تأخیر اجازه کار میدهد. Deep Doze (خواب عمیق) بعد از 60–90 دقیقه بیحرکتی رخ میدهد و وظایف پسزمینه را با پنجرههای سرویس تا 12 ساعت به شدت محدود میکند.
Doze درخواستهای شبکه را مسدود میکند، AlarmManager را به تعویق میاندازد (به جز setAndAllowWhileIdle)، WakeLock را به زور آزاد میکند و JobScheduler را در پنجرههای سرویس گروهبندی میکند. استثنا — Foreground Service، FCM high-priority و برنامههای Whitelist کاربر.
مجوز REQUEST_IGNORE_BATTERY_OPTIMIZATIONS را در مانیفست درخواست کنید و Intent با اکشن ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS ارسال کنید. سیستم دیالوگی به کاربر نشان میدهد. اضافه شدن به Whitelist امتیازی است که گوگل توصیه میکند فقط برنامههای حیاتی استفاده کنند.
از دستورات ADB استفاده کنید: adb shell dumpsys deviceidle force-idle deep برای ورود به Deep Doze، adb shell dumpsys deviceidle step light برای Light Doze، adb shell dumpsys deviceidle unforce برای خروج. عملکرد WorkManager، AlarmManager و FCM را در هر حالت بررسی کنید.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید