ANR 类型分类。
1、 KeyDispatchTimeout(5 seconds) –主要类型按键或触摸事件在特定时间内无响应。按键或者触摸引起的ANR的时间定于是在AMS中 static final int KEY_DISPATCHING_TIMEOUT = 5*1000 设置的。
2、 BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成。
3、 ServiceTimeout(20 seconds) –小概率类型 Service在特定的时间内无法处理完成。导致ANR的原因有以下几种:
1、当前的事件没有机会得到处理(即UI线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)。
2、当前的事件正在处理,但没有及时完成。避免ANR的方式:
1、UI线程尽量只做跟UI相关的工作。
2、 耗时的工作(比如数据库操作,I/O,连接网络或者别的有可能阻碍UI线程的操作)把它放入单独的线程处理。
3、 尽量用Handler来处理UIthread和别的thread之间的交互。优化UI的布局,可以采用Dump View Hierarchy,详见 https://blog.csdn.net/wangqiubo2010/article/details/79731317。
ANR分析,可以通过android studio 的DDMS中的Log 或者 手机 /data/anr/..目录中的ANR文件 来对ANR进行分析。
1、测试源码,按钮点击事件中,Thread.sleep(10000) 沉睡 10s 钟:
Button ver1 = (Button) findViewById(R.id.test_button_d);
ver1.setVisibility(View.VISIBLE);
ver1.setOnClickListener((v) -> {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent = new Intent(LoginActivity.this, VehicleMonitorActivity.class);
startActivity(intent);
});
1、DDMS中的 Log ,日志分析如下:
2、导出traces.txt,对ANRd 踪迹文件进行分析。
- 导出traces.txt文件如下:
1、adb shell ;如果提示adb 不是命令,则 在环境配置 Path中增加SDK所在地址,例如D:\develop tool\sdk\platform-tools。
2、cd /data/anr
3、ls,可以查看anr中所有文件。
4、退出shell命令,(ctrl +d)。
5、adb pull /data/anr,则将手机中发送的anr文件全部导入了启动adb命令的文件夹中。
上图中,data/anr 中 发生ANR的文件有 5个。
- 分析traces.txt,详解图截图。