最近在做一些App OEM 相关的工作,在Monkey 测试中,表现的不是很好,所以做了一些梳理工作。
- Android ANR的原因。
- Android ANR 的分类。
- Android ANR 的排查。
- Android ANR 的解决。
1 .Android ANR的原因
ANR:Application Not Responding,即应用无响应。其实说句人话,就是在Main Thread 做了不该做的事情。就这个原因。
2 . Android ANR的分类
ANR一般有三种类型:
KeyDispatchTimeout(5 seconds) –主要类型按键或触摸事件在特定时间内无响应
BroadcastTimeout(10 seconds) –BroadcastReceiver在特定时间内无法处理完成
ServiceTimeout(20 seconds) –小概率类型 Service在特定的时间内无法处理完成
3. Android ANR的排查
ANR 一般排查会查看trace文件,但是trace文件包含的内容其实很有限。最应该看的日志是Logcat以及eventlog日志,原因很简单,Logcat日志无所不包,是最基本的日志文件。
步骤:
1. 找到ANR关键字(大写匹配)
2. 向上查找timeout关键字,这个时候能找到ANR的原因,如: Application do too much work in main thread 等。
3. 查看trace 文件找出出现的最终原因。
给出一个具体的示范。
package com.example.suj.anr;
import android.support.v4.widget.TextViewCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import java.util.concurrent.TimeUnit;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
}
@Override
protected void onResume() {
super.onResume();
// try {
// Log.e("suj","start sleep");
// TimeUnit.SECONDS.sleep(12);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
}
private void init() {
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
while (true){
}
}
});
}
}
大家可以很清晰的看到我写了一个死循环。
下面给出Logcat 的日志:
ANR时刻如下:
ANR原因如下:
trace 文件如图:
下一篇博客讲解非常规ANR的解决方法。