catalogue

  • 1. Brief introduction to ANR
  • 2. Scenario of ANR occurrence
  • 3. The principle of ANR occurrence
  • 4. What specific cases do ANR have
  • 5. How to analyze ANR
  • 6. Solutions
  • 7.ANR problem solving

Good news

  • Summary of blog notes [March 2016 to present], including Java basic and in-depth knowledge points, Android technology blog, Python learning notes, etc., including the summary of bugs encountered in daily development, of course, I also collected a lot of interview questions in my spare time, updated, maintained and corrected for a long time, and continued to improve… Open source files are in Markdown format! Also open source life blog, since 2012, accumulated a total of 47 articles [nearly 200,000 words], reprint please indicate the source, thank you!
  • Link address:Github.com/yangchong21…
  • If you feel good, you can star, thank you! Of course, also welcome to put forward suggestions, everything starts from small, quantitative change causes qualitative change!

1. Brief introduction to ANR

  • 1.1 What is ANR
    • ANR Activity Not responding(page does not respond)
    • ANR Application Not Responding Application does not respond
    • Since 4.0, Android has made it mandatory to enable child threads to access the network
    • If the access network in the main thread, 4.0 after the system will be thrown: android.os.Net workOnMainThreadException in the main thread network abnormalities
    • When you are connected to the Internet, you must always perform operations on the sub-thread. Any time-consuming operations that might block the main thread should be placed on the sub-thread
    • Main thread (UI thread)16ms, refresh the interface once, 60 times per second, 60 zhen/second
    • ANR(Application Not responding), refers to the Application does Not respond, the Android system for some events need to be completed within a certain time range, if the scheduled time can Not get an effective response or response time is too long, will cause ANR.
  • 1.2 The generation of ANR needs to meet three conditions
    • Main thread: ANR is generated only if the main thread response of the application process times out;
    • Timeout time: The timeout time varies depending on the context in which the ANR is generated, but ANR will occur as long as there is no response within this time limit;
    • Input events/Specific operations: Input events refer to device input events such as buttons and touch screens. Specific operations refer to functions in the life cycle of BroadcastReceiver and Service. The causes of ANR vary depending on the context in which ANR is generated.

2. Scenario of ANR occurrence

  • The main thread, blocked for more than 5 seconds, throws an ANR dialog. The ANR takes five seconds for an Activity, 10 seconds for a BroadCastReceiver, and 20 seconds for a Service (both foreground).
  • Click events (key and touch events) are not handled within 5s: Input Event Dispatching Out
  • Service Foreground 20s Background 200s Timeout Executing Service is not started
    • Service Timeout is triggered when the ams. MainHandler in the “ActivityManager” thread receives the SERVICE_TIMEOUT_MSG message.
    • There are two types of services:
      • For foreground services, the timeout is SERVICE_TIMEOUT = 20s;
      • For background services, the timeout value is SERVICE_BACKGROUND_TIMEOUT = 200s
  • BroadcastReceiver events (onRecieve method) are not processed within the specified time (10s for BroadcastReceiver, 60s for BroadcastReceiver) : Timeout of Broadcast BroadcastRecord
    • In the BroadcastReviever example, a Receiver Timeout occurs when the BroadcastReviever () method does not receive the first ANR within 10 seconds of executing the onRecieve() method. So it is possible to do ANR within 10 seconds of executing onRecieve(), so don’t work in onRecieve()
  • ContentProvider publishes content providers within 10s: timeout Publishing Content providers
  • For example, if the service foreground is 20 seconds and the background is 200 seconds, ANR will result. Where does this time come from?
    // How long we wait for a service to finish executing.
    static final int SERVICE_TIMEOUT = 20*1000;
    
    // How long we wait for a service to finish executing.
    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
    
    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
    
        void serviceTimeout(ProcessRecord proc) {
        String anrMessage = null;
    
        synchronized(mAm) {
            if (proc.executingServices.size() == 0 || proc.thread == null) {
                return;
            }
            final long now = SystemClock.uptimeMillis();
            final long maxTime =  now -
                    (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
            ServiceRecord timeout = null;
            long nextTime = 0;
            for (int i=proc.executingServices.size()-1; i>=0; i--) {
                ServiceRecord sr = proc.executingServices.valueAt(i);
                if (sr.executingStart < maxTime) {
                    timeout = sr;
                    break;
                }
                if(sr.executingStart > nextTime) { nextTime = sr.executingStart; }}if(timeout ! = null && mAm.mLruProcesses.contains(proc)) { Slog.w(TAG,"Timeout executing service: " + timeout);
                StringWriter sw = new StringWriter();
                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
                pw.println(timeout);
                timeout.dump(pw, "");
                pw.close();
                mLastAnrDump = sw.toString();
                mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
                mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
                anrMessage = "executing service " + timeout.shortName;
            } else{ Message msg = mAm.mHandler.obtainMessage( ActivityManagerService.SERVICE_TIMEOUT_MSG); msg.obj = proc; mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT)); }}if(anrMessage ! = null) { mAm.mAppErrors.appNotResponding(proc, null, null,false, anrMessage); }}Copy the code

3. The principle of ANR occurrence

  • About the principle of ANR mechanism implementation, you can read this article first. Personally, I think it is very good, you can read it: gityuan.com/2016/07/02/…
  • The principle is as follows:
    • 1. Call Hander.sendMessageatTime () to send an ANR message after the relevant operation. The delay time is the ANR time (for example, the activity is 5s after the current time).
    • 2. Perform related operations
    • 3. Remove the message after the operation is complete. ANR occurs when the message is fetched and executed by handler if the operation is not completed by the specified time.

4. What specific cases do ANR have

  • Acitvity Fragment violent click events may lead to ANR
  • During breakpoint debugging, the program may have unlimited ANR response
  • The main thread does time-consuming operations, such as querying database data, resulting in ANR

5. How to analyze ANR

  • The ANR problem is caused by the main thread’s tasks not finishing within the specified time. The reasons for this problem are as follows:
    • The main thread is doing some time-consuming work that causes the thread to stall
    • The main thread is locked by another thread
    • The CPU is occupied by another process. The process is not allocated enough CPU resources. Procedure
  • Then look at the ANR log. When ANR occurs, the system will collect anR-related information for the developer. First, the ANR information will be collected in the Log. Second, the CPU usage during ANR will be collected, and trace information will be collected, that is, the execution status of each thread at that time. The trace.txt file is saved to /data/anr/ trace.txt
    • Find ANR generated information from log: it will contain ANR time, process, ANR type and other information.
    • After this log, there will be CPU usage information, indicating the CPU usage before and after ANR (log indicates the time when ANR is intercepted). The following points can be analyzed from various CPU usage information:
      • If the CPU usage of some processes is high and occupies almost all THE CPU resources, and the CPU usage of the ANR process is 0% or very low, the CPU resources are occupied and the process is not allocated enough resources, which results in ANR. Most of this can be thought of as a system state problem, not caused by the application.
      • If the CPU usage of the ANR process is high, such as 80% or more than 90%, it can be suspected that some codes in the application consume CPU resources improperly, such as the occurrence of an infinite loop or many threads executing tasks in the background, etc., which needs to be further analyzed in combination with the log before and after trace and ANR.
      • If the total CPU usage is not high, this process and other processes are consuming too much, there is a probability that some main processes are taking too long to operate, or that the main process is locked.
    • In addition to analyzing CPU usage above, identifying the problem required further analysis of the trace file. The trace file records the stack of each thread of the process before and after ANR occurs. The most valuable thing for us to analyze ANR is the stack of the main thread. Generally, the trace of the main thread may have the following situations:
      • The main thread is running or native, and the corresponding stack corresponds to the function in our application, so it is likely that the timeout occurred when executing this function.
      • The main thread is blocked: it is obvious that the thread is locked, so you can see which thread is locked and consider optimizing your code. If it is a deadlock problem, it is even more important to resolve it in a timely manner.
      • ANR -> ANR -> ANR -> ANR -> ANR -> Trace -> ANR -> ANR -> Trace -> ANR -> ANR -> Trace -> ANR -> Trace
  • In conclusion, there are two questions
    • 1. The problem of the CPU
      • In the monkeylog. log file, locate the “anr in” position and check the CPU usage. If the CPU usage is close to 100%, the CPU is faulty.
      • Then locate the “not responding” occurrence time in logcat.log file, and intercept the cpuInfo. log 5s before and after the time point, and calculate the CPU usage to see which process is using more, and analyze the CPU usage of the module as appropriate.
    • 2. The problem of GC
      • Locate the “not responding” occurrence time in the logcat.log file;
      • Check the trace file corresponding to ANR time point and locate the application registration. If the main Thread of Dalvik Thread shows “SUSPENDED”, it is a memory problem.
      • Intercept the log of 5s before ANR occurrence time point and analyze the Paused GC time printed by “DalviKVM”. If it is too much, it will be identified as GC problem, and we need to check the time-consuming operations of 5s.

6. Solutions

  • Put all time-consuming operations such as network access, Socket communication, querying a large number of SQL statements, complex logic calculations, etc. into child threads, and then update the UI via handler.sendMessage, runonUIThread, AsyncTask, etc. Make sure the user interface is smooth at all costs. If a time-consuming operation requires the user to wait, a degree bar can be displayed on the interface.
  • Use AsyncTask to process time-consuming I/O operations. In some synchronous operations, the main thread may be locked and need to wait for other threads to release the corresponding lock to continue execution, which has a certain ANR risk. In this case, asynchronous threads can also be used to execute the corresponding logic. Also, avoid deadlocks.
  • Using Thread or HandlerThread, call Process. SetThreadPriority (Process. THREADPRIORITYBACKGROUND) set priority, otherwise, still can reduce response program, Because the default Thread has the same priority as the main Thread.
  • Instead of blocking the main Thread with thread.wait () or thread.sleep (), use handlers to process worker Thread results.
  • Try to avoid time-consuming code in the Activity’s onCreate and onResume callbacks
  • IntentService is recommended for onReceive code in BroadcastReceiver to minimize time consumption.
  • The lifecycle functions of each component should not have time-consuming operations, even for a background Service or ContentProvider. When the application is running in the background, its onCreate() will not have user input causing an event to go unanswered ANR. However, long execution time can also cause ANR of Service and ANR of ContentProvider

7.ANR problem solving

  • Does ANR have exception logs? Or does ANR have a log in the third party crash log?
    • There is no Exception log because it is not an Error or Exception

About other content introduction

01. About blog summary links

  • 1. Tech blog round-up
  • 2. Open source project summary
  • 3. Life Blog Summary
  • 4. Himalayan audio summary
  • 5. Other summaries

02. About my blog

  • My personal website: www.yczbj.org, www.ycbjie.cn
  • Github:github.com/yangchong21…
  • Zhihu: www.zhihu.com/people/yang…
  • Jane: www.jianshu.com/u/b7b2c6ed9…
  • csdn:my.csdn.net/m0_37700275
  • The Himalayan listening: www.ximalaya.com/zhubo/71989…
  • Source: China my.oschina.net/zbj1618/blo…
  • Soak in the days of online: www.jcodecraeer.com/member/cont.
  • Email address: [email protected]
  • Blog: ali cloud yq.aliyun.com/users/artic… 239.headeruserinfo.3.dT4bcV
  • Segmentfault headline: segmentfault.com/u/xiangjian…

Project address: github.com/yangchong211