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

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

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

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

AlarmManager

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

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

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

המלצה

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

  • כדי להחליט אם להשתמש במשימה מתוזמנת לא מדויקת או במשימה ברגע מדויק, עיינו בקטע בחירת סוג ההתראה. אם ההתראה לא צריכה להיות מדויקת, כדאי להשתמש בהתראות לא מדויקות כדי לתת למערכת יותר גמישות בתזמון, מה שיכול לשפר את חיי הסוללה.
  • חשוב לשים לב למכסות ההתראות שהמערכת אוכפת ולתכנן את האפליקציה כך שתעמוד בהן.
  • הימנעו מביצוע עבודה ממושכת ב-method‏ 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 שניות כדי להשתמש בלוגיקה של אצווה בחיישן ולהפחית את מספר ההפרעות שהאפליקציה מקבלת. כשהמכשיר יתעורר לאחר מכן על ידי טריגר אחר, כמו אינטראקציה של המשתמש, אחזור מיקום או משימה מתוזמנת, המערכת תשלח מיד את נתוני החיישנים שנשמרו במטמון.
  • אם האפליקציה דורשת גם נתוני מיקום וגם נתוני חיישנים, צריך לסנכרן את השליפה והעיבוד של האירועים שלהם. כשמשלבים את קריאות החיישנים עם חסימת מצב השינה הקצרה שהמערכת מבצעת לצורך עדכון לגבי מיקום, לא צריך חסימת מצב שינה כדי שהמעבד (CPU) יישאר פעיל. כדי לטפל בהעלאה ובעיבוד של הנתונים המשולבים האלה, צריך להשתמש ב-worker או בחסימת מצב שינה לזמן קצר.

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

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

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

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

המלצה

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

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

JobScheduler

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

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

השמות של חסימות מצב השינה ש-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

המלצה

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

מיקום

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

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

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

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

המלצה

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

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

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

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

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

המלצה

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

WorkManager

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

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

השמות של חסימות מצב השינה ש-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

כברירת מחדל, שם ה-worker הוא <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 ואילך, משתמשים ב-method‏ setTraceTag ב-worker כדי להוסיף עוד מידע על תוצאות ניפוי הבאגים, כמו המחלקה שתזמנה את ה-worker.
  • אם אתם מזהים חסימות מצב שינה שנוצרו על ידי WorkManager עם שימוש גבוה בחסימות מצב שינה, יכול להיות שהגדרתם באופן שגוי את ה-worker כך שלא יושלם בתרחישים מסוימים. כדאי לנתח את הסיבות לעצירת ה-worker, במיוחד אם יש הרבה מקרים של STOP_REASON_TIMEOUT.
  • בנוסף לרישום הסיבות לעצירת ה-worker, כדאי לעיין במאמרי העזרה שלנו בנושא ניפוי באגים ב-workers. כדאי גם לאסוף ולנתח עקבות מערכת כדי להבין מתי מתבצעת רכישה ושחרור של חסימות מצב שינה.

_UNKNOWN

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

המלצה

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