Wake lock های ایجاد شده توسط API های دیگر را شناسایی کنید

چندین کتابخانه و API سیستم می‌توانند قفل‌های بیداری (wake lock) را که به برنامه شما مربوط می‌شوند، دریافت کنند. این امر می‌تواند شناسایی قفل بیداری در برنامه شما را که ممکن است باعث ایجاد مشکل شود، دشوار کند. اگر از یک API سوءاستفاده کنید، ممکن است منجر به این شود که برنامه شما برای مدت طولانی قفل بیداری را نگه دارد، حتی اگر مستقیماً APIهای قفل بیداری را فراخوانی نکنید.

در سناریوهایی که قفل بیداری توسط سایر APIها به دست می‌آید، باید از به دست آوردن قفل بیداری به صورت دستی خودداری کنید.

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

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

مدیر هشدار

AlarmManager قفل‌های بیداری را دریافت کرده و آنها را به برنامه فراخوانی کننده نسبت می‌دهد. AlarmManager هنگام به صدا درآمدن زنگ هشدار، قفل بیداری را دریافت می‌کند و هنگامی که اجرای متد onReceive() مربوط به پخش زنگ هشدار به پایان رسید، قفل را آزاد می‌کند.

نام‌های قفل بیدارباش

AlarmManager قفل‌های بیداری با نام *alarm* ایجاد می‌کند. (ستاره‌ها بخشی از نام قفل بیداری هستند، آنها نماد wild card نیستند.)

توصیه

برای بهینه‌سازی رفتار هشدار، روش‌های زیر را توصیه می‌کنیم:

  • از AlarmManager برای بهینه‌سازی زمان‌بندی آلارم استفاده کنید.
  • فقط در صورت لزوم از آلارم‌های نوع RTC_WAKEUP (که دستگاه را بیدار می‌کنند) استفاده کنید.
  • استفاده از هشدارها را به حداقل برسانید و از انجام کارهای طولانی در متد onReceive() خودداری کنید.

صدا و رسانه

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

نام‌های قفل بیدارباش

رابط‌های برنامه‌نویسی رسانه، قفل‌های بیداری را با نام‌های مختلفی که با Audio شروع می‌شوند، به دست می‌آورند:

  • AudioBitPerfect : برای پخش بدون افت کیفیت صدای USB استفاده می‌شود.
  • AudioDirectOut : برای پخش بدون افت کیفیت صدا در تلویزیون یا دستگاه‌های خاص استفاده می‌شود.
  • AudioDup : برای پخش اعلان‌ها هنگام اتصال از طریق بلوتوث یا USB استفاده می‌شود.
  • AudioIn : برای ضبط صدا در حالت دوربین فیلمبرداری و فعال بودن میکروفون استفاده می‌شود.
  • AudioMix : برای پخش صدا در یک دستگاه مشترک استفاده می‌شود.
  • AudioOffload : برای پخش طولانی مدت فقط موسیقی، برای برنامه‌هایی که از این حالت پشتیبانی می‌کنند، استفاده می‌شود.
  • AudioSpatial : برای پخش صدای فیلم یا موسیقی چند کاناله در دستگاه‌هایی که از صدای فضایی پشتیبانی می‌کنند، استفاده می‌شود.
  • AudioUnknown : زمانی استفاده می‌شود که سایر شرایط صدق نمی‌کنند.
  • MmapCapture : برای ضبط صدا با تأخیر کم استفاده می‌شود.
  • MmapPlayback : برای پخش با تأخیر کم، مانند بازی یا برنامه‌های صوتی حرفه‌ای، استفاده می‌شود.

توصیه

ما روش‌های عملی زیر را توصیه می‌کنیم:

  • از نام‌های قفل بیداری که با Audio شروع می‌شوند، استفاده نکنید.
  • اگر از APIهای رسانه استفاده می‌کنید، نیازی به دریافت مستقیم قفل‌های بیداری ندارید؛ می‌توانید برای دریافت قفل‌های بیداری لازم به APIها تکیه کنید.
  • وقتی از رابط‌های برنامه‌نویسی کاربردی رسانه استفاده می‌کنید، وقتی دیگر به جلسه رسانه نیاز ندارید، آن را خاتمه دهید.

بلوتوث

رابط‌های برنامه‌نویسی کاربردی (API) بلوتوث پلتفرم، در حین انجام اقدامات بلوتوث، هیچ قفل بیداری (wake lock) مربوط به برنامه را نگه نمی‌دارند. برای کمک به تأیید انتقال بلوتوث در پس‌زمینه، می‌توانید با استفاده از WorkManager یک وظیفه را زمان‌بندی کنید.

توصیه

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

سنسورهای دستگاه

روش‌های مختلفی برای ردیابی داده‌های حسگر دستگاه مانند شمارش گام، داده‌های شتاب‌سنج یا ژیروسکوپ وجود دارد.

در Wear OS، از Wear Health Services برای دریافت داده‌های دستگاه مانند ارتفاع، ضربان قلب و مسافت طی شده استفاده کنید.

اگر داده‌ها توسط برنامه‌های دیگر جمع‌آوری می‌شوند، می‌توانید از Health Connect همراه با WorkManager برای بازیابی داده‌ها استفاده کنید.

برای سناریوهایی مانند ردیابی دلتای گام‌ها یا مسافت طی شده، می‌توانید از Recording API در موبایل به همراه WorkManager برای بازیابی داده‌ها استفاده کنید.

در شرایط خاص، ممکن است ردیابی حسگر دستگاه سفارشی با استفاده از SensorManager مورد نیاز باشد. SensorManager قفل‌های بیداری را از طرف برنامه دریافت نمی‌کند، مگر اینکه حسگر، حسگر بیدارباش باشد که می‌توان آن را با استفاده از API isWakeUpSensor شناسایی کرد.

توصیه

استفاده از حسگرها برای ضبط با نرخ نمونه‌برداری بالا می‌تواند باتری را به میزان قابل توجهی تخلیه کند، در اینجا توصیه‌هایی برای کاهش تخلیه باتری و استفاده از قفل بیدارباش ارائه شده است:

  • اگر ردیابی شامل شمارش گام‌ها یا مسافت طی شده باشد، از API ضبط برای ضبط داده‌ها به روشی با مصرف بهینه باتری استفاده کنید.
  • برای ردیابی غیرفعال حسگر در Wear OS، از Wear Health Services برای بهینه‌سازی مصرف باتری استفاده کنید.
  • فرکانس سنسور خود را به کمتر از ۲۰۰ هرتز کاهش دهید.
  • هنگام ثبت یک سنسور با SensorManager ، برای استفاده از منطق دسته‌بندی سنسورها و کاهش تعداد وقفه‌های دریافتی برنامه، maxReportLatencyUs را بیش از 30 ثانیه تعریف کنید.
  • از نگه داشتن قفل بیداری طولانی مدت برای کل مدت ردیابی حسگر خودداری کنید، در عوض با استفاده از AlarmManager، آلارم‌ها را طوری برنامه‌ریزی کنید که هر 30+ ثانیه از داده‌های حسگر نظرسنجی کنند.

پیام ابری فایربیس (FCM)

قفل بیداری هنگام ارسال یک پیام ابری Firebase (FCM) به برنامه ایجاد می‌شود. قفل بیداری پس از اتمام اجرای متد onMessageReceived() در پیام ابری FCM آزاد می‌شود.

نام‌های قفل بیدارباش

یک قفل بیداری با نام GOOGLE_C2DM ایجاد می‌شود.

توصیه

ما روش‌های زیر را برای بهینه‌سازی رفتار FCM توصیه می‌کنیم:

  • فرکانس تحویل FCM را بهینه کنید.
  • از FCM با اولویت بالا استفاده نکنید، مگر اینکه پیام واقعاً نیاز به ارسال فوری داشته باشد.
  • متد onMessageReceived() را در اسرع وقت تکمیل کنید. برای اطلاعات بیشتر به راهنمای firebase مراجعه کنید.

زمانبند کار

وظایف JobScheduler هنگام اجرای وظایف در پس‌زمینه، قفل‌های بیداری (wake locks) را به دست می‌آورند. این قفل‌های بیداری به برنامه‌ای که workerها را ایجاد کرده است، نسبت داده می‌شوند.

نام‌های قفل بیدارباش

نام‌های قفل بیداری که توسط JobScheduler انتخاب می‌شوند، به نسخه سیستم اندرویدی که روی آن اجرا می‌شوند و هدف کار بستگی دارند.

مواردی که بین دو علامت براکت قرار گرفته‌اند، متغیر هستند. برای مثال، "<package_name>" نام بسته برنامه شماست، نه متن تحت‌اللفظی <package name> . با این حال، *job* دنباله کاراکتری *job* با ستاره است؛ ستاره‌ها به عنوان wild card استفاده نمی‌شوند.

اندروید ۱۵ و پایین‌تر

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

*job*u/@<name_space>@/<package_name>/<classname>

مشاغل دیگر از این الگو استفاده می‌کنند:

*job*/@<name_space>@/<package_name>/<classname>
اندروید ۱۶ و بالاتر

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

*job*u/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

کارهای تسریع‌شده از این الگو استفاده می‌کنند:

*job*e/@<name_space>@/#<trace_tag>#/<package_name>/<classname>

مشاغل معمولی از این الگو استفاده می‌کنند:

*job*r/@<name_space>@/#<trace_tag>#/<package_name>/<classname>
مثال

فرض کنید یک کار تسریع‌شده با فضای نام backup وجود دارد و برچسب ردیابی started . نام بسته com.example.app است و کلاسی که کار را ایجاد کرده com.backup.BackupFileService است.

در دستگاه‌هایی که اندروید ۱۵ یا پایین‌تر دارند، قفل بیدارباش به این صورت نامگذاری می‌شود:

*job*/@backup@/com.example.app/com.backup.BackupFileService

در دستگاه‌هایی که اندروید ۱۶ یا بالاتر دارند، قفل بیدارباش به صورت زیر نامگذاری می‌شود:

*job*e/@backup@/#started#/com.example.app/com.backup.BackupFileService

توصیه

میزان استفاده خود از وظایف JobScheduler را بررسی کنید. به طور خاص، از راهنمایی‌های ما برای بهینه‌سازی مصرف باتری برای APIهای زمان‌بندی وظایف پیروی کنید.

مکان

LocationManager و FusedLocationProviderClient از قفل‌های بیداری برای دریافت و ارائه موقعیت مکانی دستگاه استفاده می‌کنند. قفل‌های بیداری به برنامه‌ای که آن APIها را فراخوانی کرده است، نسبت داده می‌شوند.

نام‌های قفل بیدارباش

سرویس‌های موقعیت مکانی از نام‌های زیر استفاده می‌کنند:

  • CollectionLib-SigCollector
  • NetworkLocationLocator
  • NetworkLocationScanner
  • NlpCollectorWakeLock
  • NlpWakeLock
  • *location*

توصیه

  • بهینه‌سازی استفاده از موقعیت مکانی . برای مثال، تنظیم زمان‌های انتظار، درخواست‌های دسته‌ای موقعیت مکانی یا استفاده از به‌روزرسانی‌های غیرفعال موقعیت مکانی.
  • اگر از APIهای مکان استفاده می‌کنید، نیازی به دریافت مستقیم قفل‌های بیداری ندارید؛ می‌توانید برای دریافت قفل‌های بیداری لازم به APIها تکیه کنید.

مدیر کار

Workerهای WorkManager هنگام اجرای وظایف در پس‌زمینه، قفل‌های بیداری (wake locks) را دریافت می‌کنند. این قفل‌های بیداری به برنامه‌ای که Workerها را ایجاد کرده است، نسبت داده می‌شوند.

نام‌های قفل بیدارباش

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

اندروید ۱۵ و پایین‌تر

وظایف WorkManager قفل‌های بیداری با نام‌هایی مطابق با این الگو ایجاد می‌کنند:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
اندروید ۱۶ و بالاتر

وظایف تسریع‌شده، قفل‌های بیداری با نام‌هایی مطابق با این الگو ایجاد می‌کنند:

*job*e/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

وظایف منظم از این الگو پیروی می‌کنند:

*job*r/#<trace_tag>#/<package_name>/androidx.work.impl.background.systemjob.SystemJobService

به طور پیش‌فرض، <trace_tag> نام worker است.

مثال

فرض کنید یک کارگر تسریع‌شده به نام BackupFileWorker وجود دارد. نام بسته آن com.example.app است.

در دستگاه‌هایی که اندروید ۱۵ یا پایین‌تر دارند، قفل بیدارباش به این صورت نامگذاری می‌شود:

*job*/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

در دستگاه‌هایی که اندروید ۱۶ یا بالاتر دارند و از WorkManager 2.10.0+ استفاده می‌کنند، قفل بیدارباش به صورت زیر نامگذاری می‌شود:

*job*e/#BackupFileWorker#/com.example.app/androidx.work.impl.background.systemjob.SystemJobService

توصیه

_ناشناس

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

توصیه

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