זיהוי ואופטימיזציה של תרחישים לדוגמה לשימוש ב-wake lock

המסמך הזה עוזר לכם לזהות ולבצע אופטימיזציה של תרחישי שימוש בחסימות מצב שינה באפליקציה, וגם להדגיש אם יש חסימות מצב שינה שנרכשו על ידי ספריות אחרות או ממשקי API של המערכת שמשויכים לתרחיש השימוש הזה. מכיוון שחסימות מצב השינה האלה משויכות לאפליקציה שלכם, יכול להיות שיהיה קשה לזהות את המקור של חסימת מצב שינה בעייתית. שימוש לא נכון בממשקי API עלול לגרום לסימון האפליקציה בגלל שימוש מוגזם בחסימות מצב שינה, גם אם לא הגדרתם אותן במפורש.

במאמר הזה מפורטים כמה שמות נפוצים של חסימות מצב שינה שאולי תיתקלו בהם כשמשתמשים בכלים לניפוי באגים של חסימות מצב שינה או בדוחות ממדדי תפקוד האפליקציה. השמות האלה יכולים להגיע מ-API של ספרייה או מערכת, או שהם יכולים להיות מעורפלים. אפשר להשתמש בכלים לניפוי באגים כדי לזהות חסימות מצב שינה שמתנהגות בצורה לא תקינה, ואז לחפש את השם של חסימת מצב השינה במסמך הזה כדי לגלות איזה API עלול לגרום לבעיה, ולקבל המלצות לאופטימיזציה של השימוש בו.

במסמך הזה מפורטים תרחישי שימוש נפוצים לרכישת חסימות מצב שינה, שמות חסימות מצב השינה שמשמשים ממשקי API וספריות שונים, וכן המלצות ושיטות מומלצות לאופטימיזציה ולצמצום השימוש בחסימות מצב שינה.

AlarmManager

AlarmManager מקבלת חסימות מצב שינה ומקצה אותן לאפליקציה שקוראת לה. AlarmManager מקבלת את חסימת מצב השינה כשההתראה מופעלת, ומשחררת את החסימה כשהשידור של ההתראה, onReceive(), מסתיים.

שמות של חסימות מצב שינה

AlarmManager יוצרת חסימות מצב שינה עם השם *alarm*. (הכוכביות הן חלק מהשם של חסימת מצב שינה, הן לא מייצגות תווים כלליים לחיפוש).

המלצה

כדי לבצע אופטימיזציה של התנהגות ההתראות, מומלץ לפעול לפי השיטות המומלצות הבאות:

  • כדי להחליט אם להגדיר התראה לא מדויקת או מדויקת, אפשר לעיין במאמר בנושא בחירת סוג ההתראה. אם לא צריך שההתראה תהיה מדויקת, אפשר להשתמש בהתראות לא מדויקות כדי לתת למערכת יותר גמישות בתזמון, וכך לשפר את חיי הסוללה.
  • חשוב להכיר את מכסות ההתראות שהמערכת מגדירה ולתכנן את האפליקציה כך שתכבד אותן.
  • מומלץ להימנע מביצוע עבודות ארוכות בשיטה onReceive(), ולתזמן עובדים אם נדרש עיבוד נוסף אחרי ההתראה.

אודיו ומדיה

ממשקי API של מדיה יכולים לקבל נעילות השכמה בזמן הקלטה או הפעלה של אודיו. הנעילות של המכשיר בזמן שהאפליקציה פועלת משויכות לאפליקציה שמתקשרים ממנה.

שמות של חסימות מצב שינה

ממשקי API של מדיה מקבלים חסימות של מצב שינה עם שמות שונים שמתחילים ב-Audio:

  • AudioBitPerfect: משמש להפעלה של אודיו ב-USB ללא אובדן נתונים.
  • AudioDirectOut: משמש להפעלת אודיו ללא אובדן נתונים בטלוויזיה או במכשיר מיוחד.
  • AudioDup: משמש להפעלת התראות בזמן חיבור באמצעות Bluetooth או USB.
  • AudioIn: משמש להקלטת אודיו במצב מצלמת וידאו כשהמיקרופון פעיל.
  • AudioMix: משמש להפעלת אודיו בהתקן נפוץ.
  • AudioOffload: משמש להפעלה ארוכת טווח של מוזיקה בלבד, באפליקציות שתומכות במצב הזה.
  • AudioSpatial: משמש להפעלה של אודיו של סרט או מוזיקה רב-ערוצי במכשירים שתומכים באודיו מרחבי.
  • AudioUnknown: משתמשים בערך הזה כששאר המצבים לא רלוונטיים.
  • MmapCapture: משמש להקלטת אודיו עם השהיה נמוכה.
  • MmapPlayback: משמש להפעלה עם השהיה נמוכה, למשל במשחקים או באפליקציות אודיו מקצועיות.

המלצה

אנחנו ממליצים על השיטות הבאות:

  • אל תצהירו על שמות של חסימת מצב שינה שמתחילים ב-Audio.
  • אם אתם משתמשים בממשקי ה-API של המדיה, אתם לא צריכים להשיג חסימות של מצב השינה באופן ישיר. אתם יכולים להסתמך על ממשקי ה-API כדי להשיג את חסימות מצב השינה הנדרשות בשבילכם.
  • כשמשתמשים בממשקי API של מדיה, צריך לסיים את סשן המדיה ואת השירות שפועל בחזית שמשויך אליו כשכבר לא צריך אותם.

Bluetooth

ממשקי ה-API של Bluetooth בפלטפורמה מחזיקים בעיקר בנעילות השכמה של ליבת המערכת בזמן שמתבצעות פעולות Bluetooth, שלא משויכות לאפליקציה.

המלצה

  • כדי להימנע מחסימת מצב שינה ידנית במהלך התאמת Bluetooth, אפשר להשתמש בהתאמת מכשיר נלווה כדי להתאים מכשירי Bluetooth.
  • כדי להבין איך מתבצעת תקשורת Bluetooth ברקע, אפשר לעיין בהנחיות בנושא תקשורת ברקע.
  • בדרך כלל מספיק להשתמש ב-WorkManager אם אין השפעה על המשתמשים בגלל תקשורת מושהית. אם נדרשת חסימת מצב שינה ידנית, צריך להחזיק את חסימת מצב השינה רק למשך פעילות ה-Bluetooth או העיבוד של נתוני הפעילות.

חיישני המכשיר

יש כמה שיטות למעקב אחרי נתוני חיישנים במכשיר, כמו מספר הצעדים, נתונים של מד התאוצה או הג'ירוסקופ.

ב-Wear OS, אפשר להשתמש ב-Wear Health Services כדי לאסוף נתונים מהמכשיר, כמו גובה, דופק ומרחק.

אם הנתונים נאספים על ידי אפליקציות אחרות, אפשר להשתמש ב-Health Connect בשילוב עם WorkManager כדי לאחזר את הנתונים באופן תקופתי.

בתרחישים כמו מעקב אחרי שינוי במספר הצעדים או המרחק שעברתם, אתם יכולים להשתמש ב-Recording API בנייד בשילוב עם WorkManager כדי לאחזר את הנתונים באופן תקופתי. כדי לגשת לנתוני צעדים היסטוריים (כמו מספר הצעדים היומי או מספר הצעדים ב-6 השעות האחרונות), Health Connect תומכת גם במעקב צעדים במכשיר במכשירים עם Android בגרסה 14 ומעלה.

במצבים מסוימים, יכול להיות שיהיה צורך במעקב מותאם אישית של חיישני המכשיר באמצעות SensorManager. ‫SensorManager לא מקבל חסימות מצב שינה בשם האפליקציה, אלא אם החיישן הוא חיישן התעוררות, שאפשר לזהות אותו באמצעות API‏ isWakeUpSensor.

המלצה

שימוש בחיישנים להקלטה בקצב דגימה גבוה עלול לגרום להתרוקנות משמעותית של הסוללה. הנה המלצות לצמצום התרוקנות הסוללה והשימוש בחסימות מצב שינה:

  • אם אתם עוקבים אחרי מספר הצעדים או המרחק שעברתם, כדאי להשתמש ב-Recording API כדי לתעד את הנתונים בצורה שלא תבזבז את הסוללה. במכשירים עם Android מגרסה 14 ואילך, אפשר להשתמש ב-Health Connect כדי לגשת לנתונים היסטוריים של המכשיר ולספירת הצעדים המצטברת.
  • כדי לעקוב אחרי חיישנים פסיביים ב-Wear OS, משתמשים ב-Wear Health Services כדי לייעל את השימוש בסוללה.
  • כשרושמים חיישן ב-SensorManager, צריך להגדיר maxReportLatencyUs של יותר מ-30 שניות כדי להשתמש בלוגיקה של אצווה חיישנים ולצמצם את מספר ההפרעות שהאפליקציה מקבלת. כשהמכשיר מתעורר לאחר מכן על ידי טריגר אחר, כמו אינטראקציה של משתמש, אחזור מיקום או משימה מתוזמנת, המערכת תשלח מיד את נתוני החיישן שנשמרו במטמון.
  • אם האפליקציה דורשת גם נתוני מיקום וגם נתוני חיישנים, צריך לסנכרן את השליפה והעיבוד של האירועים. על ידי איגוד של קריאות חיישנים לחסימת מצב שינה קצרה שהמערכת מחזיקה לעדכוני מיקום, אתם נמנעים מהצורך בחסימת מצב שינה כדי לשמור על מעבד פעיל. כדי לטפל בהעלאה ובעיבוד של הנתונים המשולבים האלה, צריך להשתמש ב-worker או ב-חסימת מצב שינה לפרק זמן קצר.

הודעה בענן ב-Firebase‏ (FCM)

חסימת מצב שינה מופעלת בזמן העברת שידור של הודעה בענן ב-Firebase ‏ (FCM) לאפליקציה. חסימת מצב שינה מושבתת אחרי שהשידור של ה-FCM onMessageReceived() מסיים את ההרצה.

שמות של חסימות מצב שינה

כשמתקבלת במכשיר הודעה מ-FCM, מופעלת חסימת מצב שינה קצרה עם השם GOOGLE_C2DM. ב-Android מגרסה 16 ואילך, השם של חסימת מצב שינה הוא GCM_MESSAGE.

המלצה

כדי לייעל את ההתנהגות של FCM, מומלץ לפעול לפי השיטות המומלצות הבאות:

  • אופטימיזציה של תדירות המסירה ב-FCM.
  • אל תשתמשו ב-FCM בעדיפות גבוהה אלא אם ההודעה באמת צריכה להישלח באופן מיידי.
  • השיטה onMessageReceived() צריכה להסתיים כמה שיותר מהר, או לתזמן worker שימשיך את המשימה אם נדרש עיבוד נוסף. מידע נוסף זמין בהנחיות לגבי Firebase.

JobScheduler

משימות של JobScheduler מפעילות חסימות מצב שינה בזמן שהן מבצעות משימות ברקע. חסימות מצב השינה משויכות לאפליקציה שיצרה את העובדים.

שמות של חסימות מצב שינה

השמות של חסימות מצב שינה שמתקבלות על ידי JobScheduler תלויים בגרסה של מערכת Android שבה הן פועלות ובמטרה של העבודה.

הפריטים שמוקפים בסוגריים זוויתיים הם משתנים. לדוגמה, <package_name> הוא שם החבילה של האפליקציה, ולא הטקסט המילולי <package name>. עם זאת, *job* הוא רצף התווים *job*, עם כוכביות. הכוכביות לא משמשות כתווים כלליים לחיפוש.

‫Android מגרסה 15 ומטה

עבודות שהמשתמש מפעיל יוצרות נעילות השכמה עם שמות שפועלים לפי התבנית הבאה:

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

דוגמאות נוספות לשימוש בדפוס הזה:

*job*/@<name_space>@/<package_name>/<classname>
‫Android 16 QPR2 ואילך

עבודות שהמשתמש מפעיל יוצרות חסימות מצב שינה עם שמות שפועלים לפי התבנית הזו:

*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.

במכשירים עם Android בגרסה 15 או בגרסאות מוקדמות יותר, חסימת מצב השינה נקראת:

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

במכשירים שפועלת בהם מערכת Android 16 QPR2 ואילך, חסימת מצב השינה נקראת:

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

המלצה

  • אין לרכוש חסימת מצב שינה ידנית עבור תרחישי שימוש בהורדה/ העלאה שיזם המשתמש. במקום זאת, אפשר להשתמש ב-API של העברת נתונים שהפעילו משתמשים (UIDT). זהו הנתיב המיועד למשימות ארוכות של העברת נתונים שהמשתמש יזם.
  • אם אתם מזהים חסימות מצב שינה שנוצרו על ידי JobScheduler עם שימוש גבוה בחסימות מצב שינה, יכול להיות שהגדרתם את העבודה בצורה לא נכונה כך שהיא לא תושלם בתרחישים מסוימים. כדאי לנתח את הסיבות להפסקת העבודה, במיוחד אם אתם רואים הרבה מקרים של STOP_REASON_TIMEOUT.
  • ביצוע ביקורת על השימוש במשימות JobScheduler. בפרט, מומלץ לפעול לפי ההנחיות שלנו בנושא אופטימיזציה של השימוש בסוללה בממשקי API לתזמון משימות.

מיקום

LocationManager ו-FusedLocationProviderClient משתמשות בנעילות השכמה כדי לקבל את מיקום המכשיר ולספק אותו. החסימות החלקיות של מצב השינה משויכות לאפליקציה שקראה לממשקי ה-API האלה.

שמות של חסימות מצב שינה

שירותי המיקום משתמשים בשמות הבאים:

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

המלצה

  • כדאי לעיין בהנחיות שלנו בנושא אופטימיזציה של השימוש במיקומים. כדאי להטמיע פסק זמן, להשתמש באפשרות של שליחת בקשות למיקום בקבוצות או להשתמש בעדכונים פסיביים של המיקום.
  • לא מומלץ להשיג חסימת מצב שינה נפרדת ורציפה כדי לשמור במטמון נתוני מיקום, כי זה מיותר וצריך להסיר את זה. כשמבקשים עדכונים לגבי מיקום באמצעות ממשקי ה-API‏ FusedLocationProvider או LocationManager, המערכת מפעילה אוטומטית את המכשיר במהלך הקריאה החוזרת של אירוע המיקום. במקום זאת, אפשר לאחסן את אירועי המיקום בזיכרון או באחסון, ולעבד את אירועי המיקום מעת לעת באמצעות WorkManager.

העברת הודעות מרחוק

בקטע הזה מוסבר על תרחישים שקשורים להעברת הודעות מרחוק, שבהם יכול להיות שאפליקציות יצטרכו לשמור על חיבורים או להגיב לאירועים ממכשירים אחרים, מה שעלול להשפיע על השימוש ב-חסימת מצב שינה. תרחישים נפוצים לדוגמה:

  • אפליקציות נלוות למעקב אחר סרטונים או צלילים שצריכות לעקוב אחרי אירועים שמתרחשים במכשיר חיצוני שמחובר דרך רשת מקומית.
  • אפליקציות להעברת הודעות ששומרות על חיבור שקע רשת עם גרסה למחשב.

רוב ההוצאות ממצב שינה בתרחישי העברת ההודעות מרחוק האלה הן חסימות מצב שינה של ליבת המערכת. מכיוון שחסימות מצב שינה של ליבת המערכת לא משויכות לאפליקציה, אין כאן שמות של חסימות מצב שינה שקשורות לאפליקציה.

המלצה

  • אם אפשר לעבד את אירועי הרשת בצד השרת, צריך להשתמש ב-FCM כדי לקבל מידע על הלקוח. אם נדרש עיבוד נוסף של נתוני FCM, אפשר לתזמן תהליך מהיר.
  • אם צריך לעבד אירועים בצד הלקוח באמצעות חיבור Socket, לא צריך חסימת מצב שינה כדי להאזין להפרעות באירועים. כשמנות נתונים מגיעות לרדיו Wi-Fi או לרדיו סלולרי, חומרת הרדיו מפעילה הפרעה בצורה של חסימת מצב שינה של ליבת המערכת. אחרי כן, אפשר לתזמן worker או להשיג חסימת מצב שינה כדי לעבד את הנתונים.
  • לדוגמה, אם אתם משתמשים ב-ktor-network כדי להאזין לחבילות נתונים בשקע רשת, כדאי להפעיל את חסימת מצב שינה רק אחרי שהחבילות נמסרו ללקוח.

WorkManager

תהליכי העבודה של WorkManager מפעילים חסימות מצב שינה בזמן שהם מבצעים משימות ברקע. חסימות מצב השינה משויכות לאפליקציה שיצרה את העובדים.

שמות של חסימות מצב שינה

השמות של חסימות מצב שינה שמתקבלות על ידי WorkManager תלויים בגרסה של מערכת Android שבה הן פועלות.

‫Android מגרסה 15 ומטה

משימות של WorkManager יוצרות חסימות מצב שינה עם שמות שפועלים לפי התבנית הבאה:

*job*/<package_name>/androidx.work.impl.background.systemjob.SystemJobService
‫Android 16 QPR2 ואילך

משימות מואצות יוצרות נעילות השכמה עם שמות שמתאימים לתבנית הבאה:

*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>.

דוגמה

נניח שיש עובד עם תהליך מזורז בשם BackupFileWorker. שם החבילה הוא com.example.app.

במכשירים עם Android בגרסה 15 או בגרסאות מוקדמות יותר, חסימת מצב השינה נקראת:

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

במכשירים שמותקנת בהם גרסת Android 16 QPR2 ומעלה ומשתמשים ב-WorkManager 2.10.0+, השם של חסימת מצב שינה יהיה:

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

המלצה

  • כדי שהתגים של חסימת מצב שינה יהיו מפורטים יותר ב-Android 16 QPR2 ואילך, צריך לשדרג את הגרסה של WorkManager לגרסה היציבה האחרונה.
  • ביצוע ביקורת על השימוש ב-WorkManager workers. חשוב במיוחד לוודא שהאפליקציה פועלת בהתאם להנחיות שלנו בנושא אופטימיזציה של השימוש בסוללה בממשקי API לתזמון משימות. כדי להוסיף עוד פרטים לתגי חסימת מצב שינה ב-Android 16 QPR2 ואילך, משתמשים בשיטה setTraceTag ב-Worker כדי להוסיף עוד מידע לניפוי באגים, כמו המחלקה שתזמנה את ה-Worker.
  • אם אתם מזהים חסימות מצב שינה שנוצרו על ידי WorkManager עם שימוש גבוה בחסימות מצב שינה, יכול להיות שהגדרתם את ה-worker בצורה שגויה כך שהוא לא יושלם בתרחישים מסוימים. כדאי לנתח את הסיבות להפסקת העובד, במיוחד אם אתם רואים מקרים רבים של STOP_REASON_TIMEOUT.
  • בנוסף לרישום הסיבות להפסקת העבודה, כדאי לעיין במסמכי התיעוד שלנו בנושא ניפוי באגים בעובדים. כדאי גם לאסוף ולנתח עקבות מערכת כדי להבין מתי נרכשים ומשוחררים נעילות השכמה.

_UNKNOWN

אם כלי הניפוי באגים מזהים ששם של חסימת מצב שינה מכיל פרטים אישיים מזהים (PII), הם לא מציגים את השם האמיתי של חסימת מצב שינה. במקום זאת, הם מסמנים את חסימת מצב השינה בתווית _UNKNOWN. לדוגמה, כלים עשויים לעשות זאת אם שם ה-wake lock מכיל כתובת אימייל.

המלצה

פועלים לפי השיטות המומלצות למתן שמות לחסימת מצב שינה, ונמנעים משימוש בפרטים אישיים מזהים בשם של חסימת מצב השינה. אם מצאתם חסימת מצב שינה בשם _UNKNOWN שמשויכת לאפליקציה שלכם, נסו לזהות איזו חסימת מצב שינה זו ולתת לה שם אחר.