קל לארגן דפים בעזרת אוספים
אפשר לשמור ולסווג תוכן על סמך ההעדפות שלך.
איור 1. תיבת דו-שיח של ANR שמוצגת למשתמש.
במסמך הזה מוסבר איך מערכת Android קובעת אם אפליקציה לא מגיבה, ומוסבר איך לשמור על אפליקציה רספונסיבית.
לא משנה כמה הקוד כתוב היטב, יכול להיות שהאפליקציה עדיין תרגיש איטית, תיתקע, תיקפא לפרקי זמן משמעותיים או שייקח לה יותר מדי זמן לעבד קלט. אם האפליקציה פועלת בחזית ולא מגיבה, מוצג למשתמש דו-שיח של 'האפליקציה לא מגיבה' (ANR), כמו שמוצג באיור 1. בתיבת הדו-שיח של ANR, המשתמש יכול לצאת מהאפליקציה בכוח. אם האפליקציה לא בחזית, היא נעצרת בשקט. חשוב מאוד לתכנן את האפליקציה כך שתהיה רספונסיבית כדי לצמצם את מספר תיבות הדו-שיח של ANR.
טריגרים של ANR
באופן כללי, המערכת מציגה שגיאת ANR אם אפליקציה לא יכולה להגיב לקלט של משתמשים בשרשור הראשי – שנקרא גם שרשור ה-UI – ומונעת מהמערכת לעבד אירועי קלט של משתמשים.
לדוגמה, יכול להיות שיתרחש ANR אם אפליקציה מבצעת פעולת חסימה של קלט/פלט, כמו גישה לרשת, בשרשור ממשק המשתמש. דוגמה נוספת היא כשבאפליקציה מושקע יותר מדי זמן בבניית מבנה מורכב בזיכרון או בחישוב המהלך הבא במשחק בשרשור של ממשק המשתמש.
ב-Android, שירותי המערכת ActivityManager וWindowManager עוקבים אחרי מהירות התגובה של האפליקציה. מערכת Android מציגה את תיבת הדו-שיח ANR לאפליקציה כשהיא מזהה אחד מהתנאים הבאים:
אין תגובה לאירוע קלט – כמו אירועים של הקשת מקש או הקשה על המסך – תוך 5 שניות.
אלה טיפים כלליים שיעזרו לכם להימנע מ-ANR. לפרטים נוספים על אבחון וניפוי באגים של סוגים שונים של ANR, אפשר לעיין בדפים האחרים בקטע הזה.
חשוב לוודא שה-thread הראשי לא חסום אף פעם, ולהשתמש ב-threads בצורה אסטרטגית.
אל תבצעו פעולות חסימה או פעולות ארוכות בשרשור הראשי של האפליקציה.
במקום זאת, כדאי ליצור thread של worker ולבצע בו את רוב העבודה.
כדאי לנסות לצמצם את התחרות על הנעילה בין ה-thread הראשי לבין threads אחרים.
כדאי לצמצם את העבודה שלא קשורה לממשק המשתמש בשרשור הראשי, למשל כשמטפלים בשידורים או מפעילים שירותים. כל שיטה שמופעלת בשרשור של ממשק המשתמש צריכה לבצע כמה שפחות פעולות בשרשור הזה. בפרט, הפעילויות צריכות לבצע כמה שפחות פעולות בהגדרות שלהן בשיטות מחזור חיים מרכזיות, כמו onCreate() ו-onResume(). מידע נוסף על פתרונות זמינים לתזמון עבודה בשרשור ברקע ולתקשורת חזרה עם ממשק המשתמש מופיע במאמר סקירה כללית על עבודה ברקע.
צריך להיזהר כשמשתפים מאגרי שרשורים בין רכיבים. אל תשתמשו באותם שרשורים לפעולות שעלולות לחסום לזמן רב ולמשימות רגישות לזמן, כמו קבלת שידורים.
הפעלה מהירה של האפליקציה. צריך לצמצם את מספר הפעולות האיטיות או פעולות החסימה בקוד ההפעלה של האפליקציה, כמו שיטות שמופעלות במהלך האתחול של Dagger.
זמן הביצוע של BroadcastReceiver מוגבל כי מקלטי שידור
נועדו לבצע כמויות קטנות של עבודה בדיסקרטיות ברקע, כמו
שמירת הגדרה או רישום של Notification. לכן, כמו במקרים אחרים של קריאה לשיטות בשרשור ממשק המשתמש, אפליקציות צריכות להימנע מפעולות או מחישובים שעלולים להימשך זמן רב ב-broadcast receiver. במקום לבצע משימות ארוכות דרך השרשור של ממשק המשתמש, מבצעים אותן ברקע לביצוע מאוחר יותר. מידע נוסף על פתרונות אפשריים זמין במאמר סקירה כללית על עבודה ברקע.
בעיה נפוצה נוספת באובייקטים מסוג BroadcastReceiver מתרחשת כשהם מופעלים בתדירות גבוהה מדי. ביצוע תכוף של פעולות ברקע יכול להפחית את כמות הזיכרון שזמינה לאפליקציות אחרות. מידע נוסף על הפעלה והשבתה יעילות של אובייקטים של BroadcastReceiver זמין במאמר סקירה כללית על שידורים.
שיפור יכולת התגובה
בדרך כלל, 100 עד 200 אלפיות השנייה הוא הסף שמעבר לו המשתמשים מרגישים שהאפליקציה פועלת לאט. הנה טיפים נוספים שיעזרו לכם לגרום לאפליקציה להיראות מגיבה למשתמשים:
אם האפליקציה מבצעת פעולות ברקע בתגובה לקלט של המשתמש, צריך להציג את ההתקדמות, למשל באמצעות ProgressBar בממשק המשתמש.
במשחקים ספציפיים, המערכת מבצעת חישובים של מהלכים בשרשור של עובד.
אם לאפליקציה שלכם יש שלב הגדרה ראשוני ארוך, כדאי להציג מסך פתיחה או להציג את התצוגה הראשית במהירות האפשרית.
לציין שהטעינה מתבצעת ולמלא את המידע באופן אסינכרוני.
בכל מקרה, מומלץ לציין בדרך כלשהי שההתקדמות נמשכת, כדי שהמשתמש לא יחשוב שהאפליקציה קפאה.
כדי לזהות צווארי בקבוק בתגובתיות של האפליקציה, אפשר להשתמש בכלי ביצועים כמו Perfetto ו-CPU Profiler.
דוגמאות התוכן והקוד שבדף הזה כפופות לרישיונות המפורטים בקטע רישיון לתוכן. Java ו-OpenJDK הם סימנים מסחריים או סימנים מסחריים רשומים של חברת Oracle ו/או של השותפים העצמאיים שלה.
עדכון אחרון: 2025-07-27 (שעון UTC).
[[["התוכן קל להבנה","easyToUnderstand","thumb-up"],["התוכן עזר לי לפתור בעיה","solvedMyProblem","thumb-up"],["סיבה אחרת","otherUp","thumb-up"]],[["חסרים לי מידע או פרטים","missingTheInformationINeed","thumb-down"],["התוכן מורכב מדי או עם יותר מדי שלבים","tooComplicatedTooManySteps","thumb-down"],["התוכן לא עדכני","outOfDate","thumb-down"],["בעיה בתרגום","translationIssue","thumb-down"],["בעיה בדוגמאות/בקוד","samplesCodeIssue","thumb-down"],["סיבה אחרת","otherDown","thumb-down"]],["עדכון אחרון: 2025-07-27 (שעון UTC)."],[],[],null,["# Keep your app responsive\n\n**Figure 1.** An ANR dialog displayed to the user.\n\nThis document describes how the Android system determines whether an app isn't\nresponding and shows how to keep your app responsive.\n\nNo matter how well-written your code is, it's possible for your app to still\nfeel sluggish, hang, freeze for significant periods, or take too long to process\ninput. If your app is in the foreground and is unresponsive, the user gets an\nApplication Not Responding (ANR) dialog, as shown in figure 1. The ANR dialog\nlets the user force quit the app. If the app isn't in the foreground, then it's\nsilently stopped. It's critical to design responsiveness into your app to\nminimize ANR dialogs.\n\nANR triggers\n------------\n\nGenerally, the system displays an ANR if an app can't respond to user input on\nthe main thread---also known as the UI thread---preventing the system from\nprocessing incoming user input events.\n\nFor example, an ANR can occur if an app performs a blocking I/O operation, such\nas network access, on the UI thread. Another example is when an app spends too\nmuch time building an elaborate in-memory structure or computing the next move\nin a game on the UI thread.\n\nIn Android, app responsiveness is monitored by the [`ActivityManager`](/reference/android/app/ActivityManager) and\n[`WindowManager`](/reference/android/view/WindowManager) system services. Android displays the ANR dialog for an app\nwhen it detects one of the following conditions:\n\n- No response to an input event---such as key press or screen tap events---within 5 seconds.\n- A [`BroadcastReceiver`](/reference/android/content/BroadcastReceiver) doesn't finish executing within 10 to 20 seconds, for foreground intents. For more information, see [Broadcast receiver timeout](/topic/performance/anrs/diagnose-and-fix-anrs#broadcast-receiver-anr).\n\nAvoid ANRs\n----------\n\nThe following are general tips to avoid ANRs. For more details about diagnosing\nand debugging different types of ANRs, see the other pages in this section.\n\n- Keep the main thread unblocked at all times, and use threads strategically.\n\n - Don't perform blocking or long-running operations on the app's main thread.\n Instead, create a worker thread and do most of the work there.\n\n - Try to minimize any lock contention between the main thread and other\n threads.\n\n - Minimize any non-UI related work on the main thread, such as when handling\n broadcasts or running services. Any method that runs in the UI thread must\n do as little work as possible on that thread. In particular, activities must\n do as little as possible to set up in key lifecycle methods, such as\n `onCreate()` and `onResume()`. See [Background work overview](/guide/background) for more\n information about available solutions for scheduling work on a background\n thread and communicating back with the UI.\n\n - Be careful when sharing thread pools between components. Don't use the same\n threads for potentially long-blocking operations and time-sensitive tasks\n such as broadcast receiving.\n\n | **Note:** Because such threading usually is accomplished at the class level, you can think of responsiveness as a class problem. Compare this with basic code performance, which is a method-level concern.\n- Keep app startup fast. Minimize slow or blocking operations in the app's\n startup code, such as methods run during dagger initialization.\n\n- If you're using `BroadcastReceiver`, consider running broadcast receivers in a\n non-main thread using [`Context.registerReceiver`](/reference/android/content/Context#registerReceiver(android.content.BroadcastReceiver,%20android.content.IntentFilter,%20java.lang.String,%20android.os.Handler,%20int)). For more information,\n see [ANRs in BroadcastReceiver](#anrs-in-broadcast-receiver).\n\n - If you use [`goAsync()`](/reference/android/content/BroadcastReceiver#goAsync()), make sure [`PendingResult.finish`](/reference/kotlin/android/content/BroadcastReceiver.PendingResult?#finish) is called quickly before the ANR timeout.\n\nANRs in BroadcastReceiver\n-------------------------\n\n`BroadcastReceiver` execution time is constrained because broadcast receivers\nare meant to do small, discrete amounts of work in the background, such as\nsaving a setting or registering a [`Notification`](/reference/android/app/Notification). So, as with other\nmethods called in the UI thread, apps must avoid potentially long-running\noperations or calculations in a broadcast receiver. Instead of performing\nlong-running tasks via the UI thread, perform them in the background for later\nexecution. See [Background work overview](/guide/background) for more information about possible\nsolutions.\n\nAnother common issue with `BroadcastReceiver` objects occurs when they execute\ntoo frequently. Frequent background execution can reduce the amount of memory\navailable to other apps. For more information about how to enable and disable\n`BroadcastReceiver` objects efficiently, see [Broadcasts overview](/guide/components/broadcasts).\n| **Tip:** You can use [`StrictMode`](/reference/android/os/StrictMode) to help find potentially lengthy operations such as network or database operations that you might accidentally be doing on your main thread.\n\nReinforce responsiveness\n------------------------\n\nGenerally, 100 to 200ms is the threshold beyond which users perceive slowness in\nan app. Here are additional tips for making your app seem responsive to users:\n\n- If your app is doing work in the background in response to user input, show\n that progress is being made, such as with a [`ProgressBar`](/reference/android/widget/ProgressBar) in your UI.\n\n- For games specifically, do calculations for moves in a worker thread.\n\n- If your app has a time-consuming initial setup phase, consider showing a\n [splash screen](/develop/ui/views/launch/splash-screen) or rendering the main view as quickly as possible.\n Indicate that loading is in progress and fill the information asynchronously.\n In either case, we recommend indicating somehow that progress is being made,\n so that the user doesn't perceive that the app is frozen.\n\n- Use performance tools such as [Perfetto](/topic/performance/tracing) and [CPU Profiler](/studio/profile/cpu-profiler) to\n determine bottlenecks in your app's responsiveness."]]