Ali Baba: to give you a Demo you how to quickly locate ANR

This column focuses a large share knowledge Bat interview, follow-up will continue to update, like it trouble clicking a concern

End of the article there is information packages to receive

First, the basics of pre-reserve

1.ANR incorrectly defined : On Android, if your application is not sensitive enough for some time to respond, the system will display a dialog to the user, the dialog box called "Application not responding" (ANR: Application Not Responding) dialogue frame. Users can choose to "wait" and let the program continues to run, you can also select the "forced to shut down." Therefore, the design of the response performance is very important in the program, so that the system will not be displayed to the user ANR.

By default, the maximum execution time in Android Activity is 5 seconds (main types), the BroadcastReceiver longest execution time is 10 seconds, the maximum execution time is 20 seconds ServiceTimeout (minority type). Beyond it will prompt application not responding (ANR error).

2.ANR reasons for errors : only when the cause of the UI thread of the application response time-out will cause ANR timeouts include: ① no opportunity to deal with current events, such as the UI thread is responding to another event, current event is blocked to an event out; ② current event being processed but not too long because the time-consuming to complete timely. Other reasons: ③ do BroadcastReceiver in operation or time consuming calculations; ④CPU to high; ⑤ a deadlock occurred; ⑥ animated time-consuming operation requires a lot of computing work, it may lead to high CPU load.

Two, ANR targeting and optimization

1.ANR error location - ANR when problems arise if the development machine, the system generates a traces.txt of files in the / data / anr, the latest information at the beginning part of the ANR. By adb command to export it to local, enter the following characters:

$adb pull data/anr/traces.txt .

2. ANR optimization problem for the election of the way:

1) In order to perform time-consuming operation a long time and create a worker thread of the most convenient and efficient way is to use AsyncTask, AsyncTask only need to inherit and implement doInBackground () method to perform the task can be. In order to progress the implementation of the task presented to the user, you can perform publishProgress () method, which will trigger onProgressUpdate () callback method. In onProgressUpdate () callback method (which performs the UI thread), you can perform an operation to notify the user of progress, such as:

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    // Do the long-running work in here
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
        }
        return totalSize;
 }
 
 // This is called each time you call publishProgress()
protected void onProgressUpdate(Integer... progress) {
    setProgressPercent(progress[0]);
}

// This is called when doInBackground() is finished
protected void onPostExecute(Long result) {
    showNotification("Downloaded " + result + " bytes");
}

2) If you achieve a Thread or HandlerThread, make sure your UI thread will not wait for the work of a task execution thread away Thread.wait () or Thread.sleep (). UI thread should not have to wait for the worker thread to complete a task, you should provide a Handler UI thread to another worker, this worker thread can notify the UI thread at the end of this task by Handler. For example:
inheritance Thread class

new Thread(new Runnable() {
   @Override
   public void run() {
       /**
          耗时操作
        */
      handler.post(new Runnable() {
          @Override
          public void run() {
              /**
                更新UI
               */
          }
      });
   }
 }).start();

Implement Runnable

class PrimeRun implements Runnable {
    long minPrime;
    PrimeRun(long minPrime) {
        this.minPrime = minPrime;
    }

    public void run() {
        // compute primes larger than minPrime
         . . .
    }
}

PrimeRun p = new PrimeRun(143);
new Thread(p).start();

Use HandlerThread

// 启动一个名为new_thread的子线程
HandlerThread thread = new HandlerThread("new_thread");
thread.start();

// 取new_thread赋值给ServiceHandler
private ServiceHandler mServiceHandler;
mServiceLooper = thread.getLooper();
mServiceHandler = new ServiceHandler(mServiceLooper);

private final class ServiceHandler extends Handler {
    public ServiceHandler(Looper looper) {
      super(looper);
    }
    
    @Override
    public void handleMessage(Message msg) {
      //默认Handler的handleMessage方法是运行在主线程中的,如果传入一个工作线程的Looper,则改变HandleMessage方法执行的所在线程
    }
}

3) development of use in the daily development process Thread or HandlerThread, you can try to call Process.setThreadPriority (Process.THREAD_PRIORITY_BACKGROUND) set a lower priority, otherwise it will still reduce response program, because the default Thread main thread priority and the same.

4) Activity's onCreate and onResume callback code that try to avoid time-consuming, should do less things as much as possible, in fact, any method of execution in the UI thread should be as brief as possible quickly. Take a long time to calculate operating a similar network or DB operations and other operations may be performed for a long time, or a similar adjustment bitmap size, you should perform at work thread.

5) BroadcastReceiver in onReceive the code should minimize time-consuming. If you must perform time-consuming operations in onReceive method recommended IntentService processing, IntentService set to open automatically shut down threads and services both functions in one, itself is very flexible.

@Override
public void onReceive(Context context, Intent intent) {
    // This is a long-running operation
    BubbleSort.sort(data);
}
//上面的代码在onReceive方法中执行了耗时操作
@Override
public void onReceive(Context context, Intent intent) {
    // The task now runs on a worker thread.
    Intent intentService = new Intent(context, MyIntentService.class);
    context.startService(intentService);
}

public class MyIntentService extends IntentService {
   @Override
   protected void onHandleIntent(@Nullable Intent intent) {
       BubbleSort.sort(data);
   }
}
//将onReceive的耗时操作放入到IntentService中执行,执行完之后自动关闭工作线程

6) increase the responsiveness of the interface (interaction level), which is a sign of a mature application necessary - generally speaking, 100ms - 200ms user is able to detect the upper limit of Caton. If you are in the start-up phase of the program has a time-consuming initialization, consider displaying a splash screen, or display the main interface as soon as possible, and then immediately display the dialog box, asynchronous data loading a load. In either case, you should display a progress information, so that users feel there are circumstances Caton program.

Third, the issue of secondary processing tools ANR

1.Traceview - system performance analysis tool for positioning applications consuming operation code

process ① selected application, the application performs some operations, from the upper half of FIG., See execution time of each method of each thread ;

Minutes from the lower half of the execution time ② in the figure, the segment can be called operation specific methods and each method execution times. A percentage of the CPU;

this figure is a specific method for performing time profile, we focus on "Incl Real Time" the time in which the index, the actual method of calling time, in milliseconds, click Incl Real Time arranged when viewing the approach will be arranged according to the length of time, of which more than 500ms way we should all focus on.

2.Systrace - Android4.1 new application performance data sampling and analysis tools (with the aid when using google chorme engine jointly developed the browser)

to connect mobile phones, for a period of operation, the system will generate a Html file, Google browser open, as shown:

①Sytrace会显示在这段操作期间所有的进程信息,在其中找到自己的进程,可以看到在测试进程中,我们定位UI Thread,可以看到里面的系统方法,这是UI渲染时的调用方法,上面有一个个的圈,绿色圈代表帧渲染时间是16.6ms(Android系统渲染UI界面时间为1秒60帧,每帧即16.6ms),超过该值的帧用红色圈标注;

②点击红色圈的标注帧,可以看到Sytrace给出的Alert,具体查看可发现,给出了该帧具体的渲染时间为36.71ms,超过16.6ms,UI渲染时会发生掉帧的情况,即卡顿,再往下看,可以看到系统给出的建议和超时的主要方法。拿到这个方法再结合Traceview工具,进行具体分析,找到自己的代码,进行优化,减少耗时。

如下资料领取:
链接: https://pan.baidu.com/s/1jrK6f8mSb2GhGWNOoBYmTg 提取码: 46ed 复制这段内容后打开百度网盘手机App,操作更方便哦
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Guess you like

Origin blog.csdn.net/Android_SE/article/details/95343929