出现场景
Android规定如果5秒钟之内无法响应屏幕触摸事件或者键盘输入事件就会出现ANR,BroadcastReceiver如果10秒也没执行完操作也会出现ANR。
如何定位
怎么定位问题?当一个进程发生了ANR了以后,系统会在/data/anr目录下创建一个文件traces.txt,通过分析这个文件就能定位出ANR的原因。
先导出traces文件,其中.表示当前目录:
//导出traces文件
adb pull /data/anr/traces.txt .
//命令行查看文件
cat /data/anr/traces.txt | more
如何避免
基本的思路就是将IO操作在工作线程来处理,减少其他耗时操作和错误操作
采用异步的方式执行耗时操作。同时要注意子线程和主线程抢占同步锁的情况。
- 使用AsyncTask处理耗时IO操作。
- 使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。
- 使用Handler处理工作线程结果,而不是使用Thread.wait()或者Thread.sleep()来阻塞主线程。
- Activity的onCreate和onResume回调中尽量避免耗时的代码。
- BroadcastReceiver中onReceive代码也要尽量减少耗时,建议使用IntentService处理。