חנות און ליין לטכנאים

«חזרה לאינדקס המונחים

המונח המילוני ANR הוא ראשי תיבות של Application Not Responding (יישום אינו מגיב). זוהי בעיית ביצועים קריטית, במיוחד במערכת ההפעלה אנדרואיד, שבה התהליך הראשי של היישום (הידוע גם כתהליך ממשק המשתמש – UI thread) נחסם למשך זמן רב מדי, מה שגורם לאפליקציה להפסיק להגיב לקלט המשתמש או לאירועי מערכת.

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

הבנת הרעיון המרכזי

הבעיה הבסיסית מאחורי ANR היא חסימת התהליך הראשי.

התהליך הראשי (Main Thread / UI Thread)

לכל יישום אנדרואיד יש תהליך אחד המוקדש לטיפול בכל אינטראקציות ממשק המשתמש (UI). תהליך זה, התהליך הראשי, אחראי ל:

  1. רינדור ועדכון ממשק המשתמש (ציור אלמנטים על המסך).
  2. שיגור אירועי קלט (טיפול בלחיצות מסך, לחיצות מקשים, מחוות).
  3. הפעלת פונקציות קריאה חוזרת (Callbacks) מרכיבי מערכת שונים (כגון מתודות מחזור חיים של Activity, Broadcast Receivers או Service).

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

גורמים נפוצים ל-ANR

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

השימוש במונח ANR

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

עבור מערכת אנדרואיד

המערכת משתמשת במנגנון ANR כדי:

עבור מפתחים ואיכות האפליקציה

מפתחים משתמשים בנתוני ANR, הנאספים לעיתים קרובות באמצעות כלים כמו Android Vitals במסוף המפתחים של Google Play, כדי:

סוגי ANR וזמני הקצבה שלהם

ANR מסווגים בהתאם לרכיב שנחסם ולמשך זמן הקצבה הספציפי:

סוג ANR תיאור סף זמן קצבה (טיפוסי)
פסק זמן לשיגור קלט (נתפס על ידי משתמש) האפליקציה לא הגיבה לאירוע קלט משתמש (למשל, לחיצת מסך, הקשת מקש) בתוך מגבלת הזמן. 5 שניות
פסק זמן לביצוע Service רכיב Service אינו יכול לסיים את מתודות מחזור החיים הקריטיות שלו. מספר שניות (למשל, 10-20 שניות)
פסק זמן ל-Broadcast Receiver BroadcastReceiver לא סיים לבצע את מתודת onReceive() שלו עבור שידור מפורש. 5 שניות (אם הפעילות בחזית)
פסק זמן של startForegroundService() Service שהופעל באמצעות Context.startForegroundService() לא קרא ל-startForeground() כדי להעלות את עצמו לשירות חזית. 5 שניות
פסק זמן ל-JobScheduler JobService לא חוזר מ-onStartJob() או מ-onStopJob() מספיק מהר. מספר שניות

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

איך ANR פועל (מנגנונים)

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

  1. מנגנון ניטור: למערכת יש רכיב פנימי בשם Watchdog (כלב שמירה) שבודק מעת לעת אם התהליך הראשי מתקדם. הוא גם מנטר את תור המשימות (האירועים) הממתינים לעיבוד על ידי התהליך הראשי.
  2. זיהוי פסק זמן: כאשר אירוע מכריע (כמו אירוע מגע או שידור) נמסר לתהליך הראשי של האפליקציה, המערכת רושמת את השעה.
  3. חסימה: אם התהליך הראשי עסוק בביצוע קטע קוד ארוך (כמו קריאת רשת), הוא אינו יכול לעבד את האירוע החדש או לעדכן את ממשק המשתמש.
  4. הפעלת ANR: אם האירוע נותר ללא עיבוד, או שהתהליך נשאר חסום למשך זמן ארוך יותר מהסף (למשל, 5 שניות), המערכת קובעת שאירע ANR.
  5. תוצרי ANR: המערכת אז:
    • כותבת קובץ למכשיר (בדרך כלל /data/anr/traces.txt) המכיל מעקב מחסנית מלא (full stack trace) של התהליך הראשי וכל התהליכים האחרים בתהליך. "קובץ המעקב" הזה מצביע על שורת הקוד המדויקת שהייתה בביצוע וחסמה את התהליך.
    • מציגה את דו-שיח ה-ANR למשתמש.

תרחיש דוגמה

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

Java

button.setOnClickListener(v -> {
    // ⚠️ נוהג גרוע: בקשת רשת מופעלת על התהליך הראשי 
    downloadImageSynchronously("http://slowserver.com/large_image.jpg"); 
    // זה חוסם את התהליך למשך 8 שניות.
    // ...
});

מכיוון שהקריאה downloadImageSynchronously חוסמת את התהליך הראשי למשך 8 שניות, חריגת ה-ANR של 5 שניות נחצית. האפליקציה נראית קפואה – אין ציור מחדש של ממשק המשתמש, שום הקשה אחרת אינה נרשמת – ודו-שיח ה-ANR קופץ.

הפתרון (איך להימנע מ-ANR)

הדרך הנכונה לטפל במשימות ארוכות טווח היא לפרוק אותן לתהליך רקע (הידוע גם כ-worker thread).

Java

button.setOnClickListener(v -> {
    // ✅ נוהג טוב: פורק את המשימה הכבדה
    new Thread(() -> {
        downloadImageSynchronously("http://slowserver.com/large_image.jpg"); 
        // לאחר שסיים, עדכן את ממשק המשתמש חזרה בתהליך הראשי
        runOnUiThread(() -> {
            // עדכן אלמנט UI, כמו הצגת התמונה שהורדה
        });
    }).start();
});

פיתוח אנדרואיד מודרני מעדיף כלים כמו Kotlin Coroutines, RxJava, או ספריית WorkManager לניהול פעולות רקע אלה בצורה יעילה ובטוחה.

יתרונות וחסרונות של מנגנון ANR

יתרונות

  1. אכיפת נוהלי פיתוח טובים: מנגנון ANR מעודד מאוד מפתחים לכתוב קוד לא חוסם ולהשתמש בתכנות אסינכרוני, מה שמוביל ליישומים מובנים ובעלי ביצועים טובים יותר.
  2. שיפור חוויית המשתמש: על ידי קביעת סף ברור לרספונסיביות, הוא מבטיח שהיישומים רספונסיביים או, אם הם נכשלים, שהמשתמש מקבל דרך להתאושש (על ידי סגירת האפליקציה בכוח).
  3. אספקת נתוני איתור באגים קריטיים: קבצי מעקב ANR שנוצרים אוטומטית הם בעלי ערך רב. הם מספקים "תצלום" של מצבי התהליכים ברגע הכשל המדויק, ומאפשרים למפתחים לזהות במהירות את הקוד הבעייתי.
  4. מדד איכות: שיעור ANR הוא מדד מפתח בנראות ובאבטחת האיכות של חנות האפליקציות (Android Vitals), המניע מפתחים לייעל את האפליקציות שלהם ללא הרף.

חסרונות

  1. ספים לא גמישים: מגבלות הזמן הקבועות (למשל, 5 שניות) יכולות לפעמים להיפגע עקב גורמים שאינם בשליטת האפליקציה, כגון מכשיר איטי או עמוס במיוחד, או מחלוקת זמנית ברמת המערכת, מה שהופך את דוח ה-ANR למטעה במקצת כבאג קוד טהור.
  2. קושי בשחזור: ANR יכול להיות לסירוגין וקשה לשחזור בסביבת פיתוח מבוקרת, ולעיתים קרובות הוא מתבטא רק תחת עומס כבד או במכשירים ספציפיים וחלשים.
  3. הפרעה למשתמש: למרות שהוא הכרחי, דו-שיח ה-ANR הוא עדיין הפרעה צורמת המחייבת את המשתמש לקבל החלטה, מה שעלול להוביל לאובדן עבודה או לתסכול אם הוא סוגר את האפליקציה.
  4. מורכבות איתור באגים (עבור Deadlocks): למרות שקובץ המעקב מועיל, אבחון בעיות מורכבות כמו מבוי סתום או מחלוקת על מנעולים בין מספר תהליכים עדיין יכול להיות מאתגר, ומחייב ניתוח מעמיק של כל מחסניות התהליכים.

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

«חזרה לאינדקס המונחים