Android 性能优化(17)UI优化:Keeping Your App Responsive 拒绝ANR
Keeping Your App Responsive
In this document
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 classproblem. (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:
产生无响应对话框的原因:
- KeyDispatchTimeout(5 seconds) --主要是类型按键或触摸事件在特定时间内无响应
- BroadcastTimeout(10 seconds) --BroadcastReceiver在特定时间内无法处理完成
- ServiceTimeout(20 secends) --小概率事件 Service在特定的时间内无法处理完成
- No response to an input event (such as key press or screen touch events) within 5 seconds.
- A
BroadcastReceiverhasn'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 the doInBackground() method to perform the work. To post progress changes to the user, you can call publishProgress(), which invokes the onProgressUpdate() callback method. From your implementation of onProgressUpdate() (which runs on the UI thread), you can notify the user. For example:
通常使用避免ANR的方法就是在ui线程中只做与ui相关的工作。其它任务放到后台线程中,如使用 AsyncTask 或ThreadorHandlerThread。
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 = ;
for (int i = ; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * ));
// 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[]);
}
// 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.
使用ThreadorHandlerThread 时要注意要把线程设置为后台的,否则它和ui线程优先级相同,同样会产生ANR.
代码 Process.setThreadPriority(THREAD_PRIORITY_BACKGROUND); 设置后台。
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 call Thread.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.
不要在ui线程中,调用Thread.wait()orThread.sleep() 等待工作线程完成工作。如要它们之间有数据传输,可以使用 Handler。
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.
BroadcastReceiver 同样可以使用工作线程减少阻塞。
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 其它避免ANR的技巧
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
ProgressBarin 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 性能优化(17)UI优化:Keeping Your App Responsive 拒绝ANR的更多相关文章
- Android开发之如何避免ANR(Keeping Your App Responsive)
一:什么是ANR 如果应用程序不能响应用户的输入了,那么就可以说应用ANR了. 如果需要运行一个耗时较长的操作的时候,不要把这个任务放在UI线程上运行,而是单独创建一个线程运行那些操作. 以下情况会出 ...
- Android学习笔记_52_全面了解Android开发规范:性能及UI优化
一.Android编码规范 1.java代码中不出现中文,最多注释中可以出现中文 2.局部变量命名.静态成员变量命名 只能包含字母,单词首字母出第一个外,都为大写,其他字母都为小写 3.常量命名 只能 ...
- android 性能优化
本章介绍android高级开发中,对于性能方面的处理.主要包括电量,视图,内存三个性能方面的知识点. 1.视图性能 (1)Overdraw简介 Overdraw就是过度绘制,是指在一帧的时间内(16. ...
- Android性能优化的浅谈
一.概要: 本文主要以Android的渲染机制.UI优化.多线程的处理.缓存处理.电量优化以及代码规范等几方面来简述Android的性能优化 二.渲染机制的优化: 大多数用户感知到的卡顿等性能问题的最 ...
- Android性能优化典范(二)
Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...
- android app性能优化大汇总(google官方Android性能优化典范 - 第2季)
Google前几天刚发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的 ...
- Android性能优化典范 - 第2季
Google发布了Android性能优化典范第2季的课程,一共20个短视频,包括的内容大致有:电量优化,网络优化,Wear上如何做优化,使用对象池来提高效率,LRU Cache,Bitmap的缩放,缓 ...
- Android 性能优化探究
使用ViewStub动态载入布局.避免一些不常常的视图长期握住引用: ViewStub的一些特点: 1. ViewStub仅仅能Inflate一次,之后ViewStub对象被置空:某个被ViewStu ...
- 【腾讯Bugly干货分享】Android性能优化典范——第6季
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/580d91208d80e49771f0a07c 导语 这里是Android性能优 ...
随机推荐
- 【HDOJ3047】Zjnu Stadium(带权并查集)
题意:浙江省第十二届大学生运动会在浙江师范大学举行,为此在浙师大建造了一座能容纳近万人的新体育场. 观众席每一行构成一个圆形,每个圆形由300个座位组成,对300个座位按照顺时针编号1到300,且可以 ...
- SOJ 4454 (矩阵快速幂)
先引入数的快速幂 例如计算2的5次方,常规算法2*2*2*2*2,利用快速幂的思想,求出5的二进制表达式101,权值为1和4的位上数字为1,即2^5=2^1*2^4.代码如下,时间复杂度为O(logn ...
- POJ1328 Radar Installation 解题报告
Description Assume the coasting is an infinite straight line. Land is in one side of coasting, sea i ...
- Linux下keepalived下载安装与配置
一.下载(原文链接:http://www.studyshare.cn/blog-front//software/details/1158/0 ) 网盘下载:https://pan.baidu.com/ ...
- MongoDB小结21 - find【游标】
数据库使用游标来控制find的执行结果. 客户端对游标的实现通常能够对最终结果进行有效控制. 可以限制结果的数量,略过部分结果,对任意方向任意键的组合对结果进行排序,或者去执行一些功能强大的操作. 我 ...
- mybatis bug之resultmap缺少object-relation匹配参数password,造成设置密码不成功
1.mybatis bug之resultmap缺少object-relation匹配参数password,造成设置密码不成功 在resultmap里没有设置user类中password属性和数据库表t ...
- 记一次调试python内存泄露的问题
转载:http://www.jianshu.com/p/2d06a1a01cc3 这两天由于公司需要, 自己编写了一个用于接收dicom文件(医学图像文件)的server. 经过各种coding-de ...
- Java之旅(1)—Class类
看到Class的时候,我们是不是会一下子想到我们敲代码中的class呢?此Class非彼class,这里讲的Class类实际上就是java类的统称,我们能够将其称之为抽象的类不是详细的一个类的名字. ...
- 搭建wamp php环境
点击下载wamp,wamp是一个集成环境,在安装过程中,我们要选择默认的浏览器以及默认的文本编辑器,安装步骤如下: 第一步,选择默认的浏览器(填写默认的浏览器可执行路径就行) 第二步,选择默认的文本编 ...
- B. Error Correct System (CF Round #296 (Div. 2))
B. Error Correct System time limit per test 2 seconds memory limit per test 256 megabytes input stan ...