Android ANR分析(三)
http://www.jianshu.com/p/8964812972be
http://stackoverflow.com/questions/704311/android-how-do-i-investigate-an-anr

Figure 1. An ANR dialog displayed to the user.
It's possible to write code that wins every performance test in the world, but still feels sluggish, hang or freeze for significant periods, or take too long to process input. The worst thing that can happen to your app's responsiveness is an "Application Not Responding" (ANR) dialog.
In Android, the system guards against applications that are insufficiently responsive for a period of time by displaying a dialog that says your app has stopped responding, such as the dialog in Figure 1. At this point, your app has been unresponsive for a considerable period of time so the system offers the user an option to quit the app. It's critical to design responsiveness into your application so the system never displays an ANR dialog to the user.
This document describes how the Android system determines whether an application is not responding and provides guidelines for ensuring that your application stays responsive.
What Triggers ANR?
Generally, the system displays an ANR if an application cannot respond to user input. For example, if an application blocks on some I/O operation (frequently a network access) on the UI thread so the system can't process incoming user input events. Or perhaps the app spends too much time building an elaborate in-memory structure or computing the next move in a game on the UI thread. It's always important to make sure these computations are efficient, but even the most efficient code still takes time to run.
In any situation in which your app performs a potentially lengthy operation, you should not perform the work on the UI thread, but instead create a worker thread and do most of the work there. This keeps the UI thread (which drives the user interface event loop) running and prevents the system from concluding that your code has frozen. 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.)
In Android, application responsiveness is monitored by the Activity Manager and Window Manager system services. Android will display the ANR dialog for a particular application when it detects one of the following conditions:
- No response to an input event (such as key press or screen touch events) within 5 seconds.
- A
BroadcastReceiver
hasn't finished executing within 10 seconds.
How to Avoid ANRs
Android applications normally run entirely on a single thread by default the "UI thread" or "main thread"). This means anything your application is doing in the UI thread that takes a long time to complete can trigger the ANR dialog because your application is not giving itself a chance to handle the input event or intent broadcasts.
Therefore, any method that runs in the UI thread should do as little work as possible on that thread. In particular, activities should do as little as possible to set up in key life-cycle methods such as onCreate()
and onResume()
. Potentially long running operations such as network or database operations, or computationally expensive calculations such as resizing bitmaps should be done in a worker thread (or in the case of databases operations, via an asynchronous request).
The most effective way to create a worker thread for longer operations is with the AsyncTask
class. Simply extend AsyncTask
and implement thedoInBackground()
method to perform the work. To post progress changes to the user, you can call publishProgress()
, which invokes theonProgressUpdate()
callback method. From your implementation of onProgressUpdate()
(which runs on the UI thread), you can notify the user. For example:
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");
}
}
To execute this worker thread, simply create an instance and call execute()
:
new DownloadFilesTask().execute(url1, url2, url3);
Although it's more complicated than AsyncTask
, you might want to instead create your own Thread
or HandlerThread
class. If you do, you should set the thread priority to "background" priority by calling Process.setThreadPriority()
and passing THREAD_PRIORITY_BACKGROUND
. If you don't set the thread to a lower priority this way, then the thread could still slow down your app because it operates at the same priority as the UI thread by default.
If you implement Thread
or HandlerThread
, be sure that your UI thread does not block while waiting for the worker thread to complete—do not callThread.wait()
or Thread.sleep()
. Instead of blocking while waiting for a worker thread to complete, your main thread should provide a Handler
for the other threads to post back to upon completion. Designing your application in this way will allow your app's UI thread to remain responsive to input and thus avoid ANR dialogs caused by the 5 second input event timeout.
The specific constraint on BroadcastReceiver
execution time emphasizes what broadcast receivers are meant to do: small, discrete amounts of work in the background such as saving a setting or registering a Notification
. So as with other methods called in the UI thread, applications should avoid potentially long-running operations or calculations in a broadcast receiver. But instead of doing intensive tasks via worker threads, your application should start an IntentService
if a potentially long running action needs to be taken in response to an intent broadcast.
Another common issue with BroadcastReceiver
objects occurs when they execute too frequently. Frequent background execution can reduce the amount of memory available to other apps. For more information about how to enable and disable BroadcastReceiver
objects efficiently, seeManipulating Broadcast Receivers on Demand.
Tip: You can use StrictMode
to help find potentially long running operations such as network or database operations that you might accidentally be doing on your main thread.
Reinforce Responsiveness
Generally, 100 to 200ms is the threshold beyond which users will perceive slowness in an application. As such, here are some additional tips beyond what you should do to avoid ANR and make your application seem responsive to users:
- If your application is doing work in the background in response to user input, show that progress is being made (such as with a
ProgressBar
in your UI). - For games specifically, do calculations for moves in a worker thread.
- If your application has a time-consuming initial setup phase, consider showing a splash screen or rendering the main view as quickly as possible, indicate that loading is in progress and fill the information asynchronously. In either case, you should indicate somehow that progress is being made, lest the user perceive that the application is frozen.
- Use performance tools such as Systrace and Traceview to determine bottlenecks in your app's responsiveness.
Android ANR分析(三)的更多相关文章
- Android Telephony分析(三) ---- RILJ详解
前言 本文主要讲解RILJ工作原理,以便更好地分析代码,分析业务的流程.这里说的RILJ指的是RIL.java (frameworks\opt\telephony\src\java\com\andro ...
- Android ANR 分析解决方法
一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...
- Android ANR分析(2)
转自:http://blog.csdn.net/ruingman/article/details/53118202 定义 主线程在特定的时间内没有做完特定的事情 常见的场景 A.input事件超过 ...
- Android ANR分析(1)
转自:http://blog.csdn.net/itachi85/article/details/6918761 一:什么是ANR ANR:Application Not Responding,即应用 ...
- android anr分析方法
目录(?)[+] 案例1关键词ContentResolver in AsyncTask onPostExecute high iowait 案例2关键词在UI线程进行网络数据的读写 一:什么是AN ...
- Android ANR分析及解决方案
一:什么是ANR ANR:Application Not Responding,即应用无响应. ANR定义:在Android上,如果你的应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个 ...
- [转]Android ANR 分析解决方法
一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1. KeyDispatchTimeout(5 seconds) ...
- Android 短信模块分析(三) MMS入口分析
MMS入口分析: 在Mms中最重要的两个Activity,一个是conversationList(短信列表) ,另一个就是ComposeMessageActivity(单个对话或者短信).每 ...
- Android ANR 分析
首先贴一下trace 文件 Process: com.oppo.reader PID: 20358 Time: 2933175644_1545041895232 Flags: 0x38d83e44 P ...
随机推荐
- Android坐标系统
1 背景 去年有很多人私信告诉我让说说自定义控件,其实通观网络上的很多博客都在讲各种自定义控件,但是大多数都是授之以鱼,却很少有较为系统性授之于渔的文章,同时由于自己也迟迟没有时间规划这一系列文章, ...
- OpenCV进阶之路:一个简化的视频摘要程序
一.前言 视频摘要又称视频浓缩,是对视频内容的一个简单概括,先通过运动目标分析,提取运动目标,然后对各个目标的运动轨迹进行分析,将不同的目标拼接到一个共同的背景场景中,并将它们以某种方式进行组合.视频 ...
- cvGet2D的用法
CvScalar s;s = cvGet2D(src, j,i);//获取src图像中坐标为(i,j)的像素点的值s.val[0] 代表src图像BGR中的B通道的值~int nXY = cvGet2 ...
- AutoHotkey之自问自答
偶然的机会,接触到了AutoHotkey这个东西,觉得不错,便花时间了解了一下.以此来记录我在学习AutoHotkey时遇到的各种问题,以及我对其的解释(有可能不专业甚至出错). Time:2015- ...
- 解决 QtCreator 3.5(4.0)无法输入中文的问题
解决 QtCreator 3.5.1无法输入中文的问题 [TOC] 环境是ubuntu 15.10 ubuntu软件源中下载安装的fctix-libs-qt5现在没有用,版本太旧了. 自己下载fcti ...
- NFS和mount常用参数详解
NFS权限参数配置 ro 只读访问 rw 读写访问 sync 所有数据在请求时写入共享 async NFS在写入数据前可以相应请求 secure NFS通过1024以下的安全TCP/IP端口发送 in ...
- CDN——到底用还是不用?
最近在学bootstrap,在知乎上搜索bootstrap看到有人问bootstrap基础包体积较大,对性能影响会不会很大,看到两种方法来减少对性能的影响: 有选择地部分加载,bootstrap带有L ...
- shiro学习中报错解决方法
[1] 最近在学习shiro,在学习过程中出现了一个问题,报错如下: org.apache.shiro.UnavailableSecurityManagerException: No Security ...
- CEF3开发者系列之进程间消息传递
在使用CEF3作为框架开发过程中,实现WebSockets.XMLHttpRequest.JS与本地客户端交互等功能时,需要在渲染(Render)进程和浏览(Browser)进程中传递消息.CEF3在 ...
- ACM/ICPC 之 Floyd练习六道(ZOJ2027-POJ2253-POJ2472-POJ1125-POJ1603-POJ2607)
以Floyd解法为主的练习题六道 ZOJ2027-Travelling Fee //可免去一条线路中直接连接两城市的最大旅行费用,求最小总旅行费用 //Time:0Ms Memory:604K #in ...