ניטור ANR באנדרואיד: הגדרה והתראות Slack

אפליקציית האנדרואיד שלך קופאת, משתמשים רואים מסך שחור ועוזבים, בעוד ש-Crashlytics מציג ANRs ללא stack traces, והסיבה אינה ידועה. אנחנו מגדירים ניטור ANR turnkey: מחברים את Firebase Crashlytics או Sentry, קוראים ApplicationExitInfo לקבלת traces מדויקים, ומגדירים התראות Slack. הצוות שלנו מטפל בכל המחזור—מבדיקה ועד תמיכה—כדי שתוכל למצוא ולתקן את הבעיה במהירות לפני תלונות המוניות.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

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

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

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
ניטור ANR באנדרואיד: הגדרה והתראות Slack
בינוני
מ- 4 שעות עד 2 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

מדוע ANR מסוכן לאפליקציה שלך?

תארו לעצמכם: האפליקציה שלכם קופאת למשך 5 שניות, המשתמש רואה מסך שחור וחלון סגירה. Crashlytics מדווח על ANR ללא מחסנית קריאות — רק שם ה-Activity. הסיבה לא ידועה. כך אתם מאבדים משתמשים ודירוגים ב-Google Play. לפי התיעוד הרשמי, ANR (Application Not Responding) מתרחש כאשר ה-thread הראשי חסום למשך יותר מ-5 שניות עבור אירוע קלט או 10 שניות עבור BroadcastReceiver. סיבות נפוצות כוללות תחרות על נעילות (lock contention), השהיות של איסוף זבל (GC), והחמצות מטמון דפים בקלט/פלט של דיסק.

סוג אירוע סף זמן
אירוע קלט 5 שניות
BroadcastReceiver 10 שניות
Service (startService) 20 שניות

המשתמש רואה מסך שחור ואת החלון "האפליקציה לא מגיבה", ולאחר מכן המערכת הורגת את התהליך. Crashlytics רושם ערך ללא מחסנית קריאות — רק שם ה-ANR וה-Activity. זה גרוע יותר מקריסה: ללא עקבות אינכם יודעים את הסיבה. הקמנו ניטור ANR מקצה לקצה: חיבור ל-Firebase Crashlytics או ל-Sentry, קריאת ApplicationExitInfo לקבלת עקבות מדויקות, והגדרת התראות Slack. כתוצאה מכך, אתם רואים איזה קוד גרם לקיפאון ומתקנים אותו לפני תלונות המוניות. חיסכון בזמן דיבוג עד 50%. למידע נוסף על ANR בתיעוד Android. קבלו הערכת פרויקט — כתבו לנו.

מאיפה מגיעים ANRs

לרוב זו לא קריאה כבדה אחת אלא שרשרת. לדוגמה, קורוטינה על Dispatchers.Main קוראת ל-runBlocking, שבתוכה יש Room.database.query() ללא suspend. במכשיר חלש עם דיסק עמוס, זה 5+ שניות של חסימה. מקור נפוץ נוסף הוא SharedPreferences במהלך התנעה קרה, הגורם להחמצות מטמון דפים במכשירים תקציביים.

// Антипаттерн — чтение SharedPreferences на main thread при старте
class SplashActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val token = getSharedPreferences("prefs", MODE_PRIVATE)
            .getString("auth_token", null) // блокирует main thread
    }
}

הגישה הנכונה: מעבר ל-SharedPreferences (מבוסס קורוטינות) או קריאה ב-// Антипаттерн — чтение SharedPreferences на main thread при старте class SplashActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val token = getSharedPreferences("prefs", MODE_PRIVATE) .getString("auth_token", null) // блокирует main thread } } .

השוואת כלי ניטור ANR

השוו בין שלושה פתרונות פופולריים:

כלי שיטת זיהוי מורכבות דיוק עקבות
Firebase Crashlytics Watchdog + ApplicationExitInfo (API 30+) נמוכה (שורה אחת) מוגבל (לא תמיד מחסנית)
Sentry Watchdog עם timeout ניתן להגדרה בינונית (הגדרה) גבוה (מחסנית מלאה) – 70% יותר עקבות מ-Crashlytics
Android Vitals צבירה ב-Google Play ללא SDK נתוני שיעור ANR, ללא מחסנית

Firebase Crashlytics הוא הנתיב הפשוט ביותר אם הוא כבר משולב. אך לניתוח מעמיק, השתמשו ב-Sentry או ב-DataStore. Sentry מספק 70% יותר עקבות אינפורמטיביות מ-Crashlytics. ApplicationExitInfo מדויק פי 3 מ-watchdog: הוא שומר את תמונת ה-thread המלאה ברגע ה-ANR, לא רק את המחסנית הנוכחית.

הגדרת ANR ב-Crashlytics

  1. הוסיפו את התלות ב-lifecycleScope.launch(Dispatchers.IO):
implementation("com.google.firebase:firebase-crashlytics:18.+") 
  1. אתחלו את ה-SDK ב-ApplicationExitInfo.
  2. Crashlytics רושם אוטומטית ANRs דרך build.gradle ב-API 30+ או דרך ה-watchdog שלו בגרסאות ישנות יותר.

הגדרת ANR ב-Sentry

SentryAndroid.init(this) { options ->
    options.dsn = "https://[email protected]/project"
    options.isAnrEnabled = true
    options.anrTimeoutIntervalMillis = 5000
    options.isAnrReportInDebug = false // не спамим в debug
}

Sentry מפעיל thread של watchdog שבודק כל 1000 אלפיות השנייה אם ה-thread הראשי חי. אם אין תגובה למשך יותר מ-implementation("com.google.firebase:firebase-crashlytics:18.+") , הוא לוכד את המחסנית ושולח את האירוע.

ApplicationExitInfo — המקור המדויק לעקבות

ב-Android 10+, המערכת שומרת את סיבת סיום התהליך ב-Application.onCreate(). זה מדויק פי 3 מ-threads של watchdog:

val activityManager = getSystemService(ActivityManager::class.java)
val exitReasons = activityManager.getHistoricalProcessExitReasons(null, 0, 10)
exitReasons.filter { it.reason == ApplicationExitInfo.REASON_ANR }.forEach { info ->
    info.traceInputStream?.use { stream ->
        val trace = stream.bufferedReader().readText()
        // отправляем trace в ваш мониторинг
        Log.e("ANR", trace)
    }
}

ApplicationExitInfo מכיל את תמונת ה-thread המלאה — אותם נתונים כמו ב-SentryAndroid.init(this) { options -> options.dsn = "https://[email protected]/project" options.isAnrEnabled = true options.anrTimeoutIntervalMillis = 5000 options.isAnrReportInDebug = false // не спамим в debug } . ניתן לקרוא אותו בהפעלה הבאה ולשלוח אותו ל-Sentry או ל-Datadog כקובץ מצורף.

אבחון באמצעות StrictMode

ב-build של דיבוג, StrictMode עוזר לתפוס ANRs פוטנציאליים לפני הייצור:

if (BuildConfig.DEBUG) {
    StrictMode.setThreadPolicy(
        StrictMode.ThreadPolicy.Builder()
            .detectAll()
            .penaltyLog()
            .penaltyFlashScreen()
            .build()
    )
    StrictMode.setVmPolicy(
        StrictMode.VmPolicy.Builder()
            .detectLeakedSqlLiteObjects()
            .detectLeakedClosableObjects()
            .penaltyLog()
            .build()
    )
}

anrTimeoutIntervalMillis מהבהב את המסך באדום על כל קריאת דיסק ב-thread הראשי — המפתח רואה את הבעיה מיד.

הגדרת התראות

ב-Firebase Crashlytics, הגדירו התראת מהירות (velocity alert) עבור ANRs:

  • סף: >1% מהמפגשים ללא קריסה מושפעים בשעה אחת.
  • ערוץ: webhook של Slack דרך Firebase Alert Channels.

ב-Sentry, השתמשו ב-ApplicationExitInfo עם התנאי val activityManager = getSystemService(ActivityManager::class.java) val exitReasons = activityManager.getHistoricalProcessExitReasons(null, 0, 10) exitReasons.filter { it.reason == ApplicationExitInfo.REASON_ANR }.forEach { info -> info.traceInputStream?.use { stream -> val trace = stream.bufferedReader().readText() // отправляем trace в ваш мониторинг Log.e("ANR", trace) } } .

מה כלול בהקמת ניטור ANR

  • שילוב גלאי ANR (Firebase Crashlytics, Sentry, או שניהם)
  • הגדרת קריאת traceInputStream ב-API 30+ לקבלת עקבות מדויקות
  • הפעלת StrictMode ב-builds של דיבוג לאבחון מונע
  • הגדרת התראות מהירות עם הודעת Slack
  • ניתוח קו הבסיס של Android Vitals להשוואה עם מתחרים
  • תיעוד על שחזור ANR והמלצות לתיקון
  • תמיכה לאחר ההקמה (שבועיים בחינם)

הניסיון שלנו: יותר מ-5 שנים בפיתוח Android, יותר מ-50 פרויקטי ניטור. אנו מבטיחים שיעור ANR מתחת ל-0.2% לאחר האופטימיזציה. הקמה בסיסית מתחילה ב-$500; הקמה מלאה עם Sentry ו-ApplicationExitInfo מ-$2000. השקעה זו בדרך כלל חוסכת $10,000+ בשנה בעלויות תמיכה מופחתות ועזיבת משתמשים.

כמה זמן לוקחת הקמת ניטור ANR?

הקמה בסיסית עם Firebase Crashlytics אורכת בין 4 שעות ליום אחד. אם נדרשים Sentry וניתוח /data/anr/traces.txt, זה לוקח יומיים. אנו מספקים דשבורד מוכן והתראות. צרו קשר — קבלו הערכת פרויקט מפורטת.

ציר זמן ועלות

הקמה בסיסית — בין 4 שעות ליום אחד, החל מ-$500. עם ניתוח if (BuildConfig.DEBUG) { StrictMode.setThreadPolicy( StrictMode.ThreadPolicy.Builder() .detectAll() .penaltyLog() .penaltyFlashScreen() .build() ) StrictMode.setVmPolicy( StrictMode.VmPolicy.Builder() .detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .build() ) } ודשבורד — יומיים, מ-$2000. העלות מחושבת באופן אישי לפי מורכבות הפרויקט ומספר המסכים. ההשקעה משתלמת דרך הפחתת עזיבת משתמשים. קבלו הערכה — כתבו לנו.