ניפוי באגים באפליקציה ל-Android על סמך תגי ANR במרכז הבקרה של Crashlytics

שגיאות מסוג "האפליקציה לא מגיבה" (ANR) מופעלות כששרשור ה-UI של האפליקציה לא מגיב במשך יותר מ-5 שניות. מידע נוסף על מקרי ANR ועל אבחון של מקרי ANR זמין במסמכי התיעוד של Android.

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

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

Triggered ANR

שרשור שנחסם למשך זמן רב מדי והפעיל את ה-ANR מסומן בתג Triggered ANR.

השרשור הבעייתי יכול להיות השרשור הראשי של האפליקציה, או כל שרשור שלא מגיב. עם זאת, יכול להיות שהשרשור שמתויג בתור Triggered ANR הוא לא הסיבה האמיתית ל-ANR. כדי לספק תובנות לניפוי באגים ולתיקון מקרי ה-ANR האלה, Crashlytics מתייג גם את כל ה-threads האחרים שמעורבים ב-ANR. בקטעים הבאים בדף הזה מוסבר על התגים האחרים שאפשר להוסיף לשרשור.

Deadlocked

כל השרשורים שמעורבים במבוי סתום שהוביל ל-ANR מסומנים בתג Deadlocked.

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

המלצה

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

IO Root blocking

כל שרשור שביצע פעולות קלט/פלט איטיות וחסם את השרשור Triggered ANR מסומן בתג IO Root blocking. אם ה-thread‏ Triggered ANR לא נחסם על ידי threads אחרים, אז ה-thread‏ IO Root blocking הוא גם thread‏ Root blocking.

המלצה

באופן כללי, האפליקציה לא אמורה לבצע פעולות קלט/פלט (I/O) שדורשות משאבים רבים ב-thread הראשי. אם ה-thread הראשי הוא IO Root blocking, אפשר גם להשתמש במצב קפדני כדי לזהות פעולות קלט/פלט לא מכוונות שמתרחשות ב-thread הראשי.

Root blocking

כל שרשור שחסם את השרשור שתויג בתג Triggered ANR מתויג בתג Root blocking. אם שרשור מתויג גם כ-Root blocking וגם כ-Triggered ANR, אין שרשורים אחרים שחוסמים אותו.

אם שרשורים כלשהם של Triggered ANR המתינו (אולי באופן טרנזיטיבי) לשרשורים אחרים, הם Root blocking. יכולות להיות סיבות שונות לכך ששרשור הוא שורש הבעיה של ה-ANR.

המלצה

צמצמו את העבודה שדורשת משאבי מעבד (CPU) רבים ב-thread הראשי. השתמשו ב-worker threads או ב-background threads כדי לבצע משימות שדורשות הרבה משאבי מעבד.

כדאי לצמצם את העבודה האינטנסיבית של קלט/פלט, כמו טעינה ממסד נתונים, ב-thread הראשי.

Unknown root cause

השרשור מתויג בתג Unknown root cause אם הוא הפעיל את ה-ANR אבל היה במצב של חוסר פעילות בתהליך כשה-ANR התרחש. ל-Crashlytics אין מספיק מידע כדי לקבוע מה שורש הבעיה. אין סיבה ברורה לכך שה-ANR הזה קרה.

המלצה

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

Waiting for binder call

כל שרשור שהמתין לקריאת Binder וחסם את השרשור Triggered ANR מסומן בתג Waiting for binder call. אם ה-thread Triggered ANR לא נחסם על ידי threads אחרים, אז ה-thread Waiting for binder call הוא גם thread Root blocking.

המלצה

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