一. Log
日志中 Bug
类型
- 程序异常强制关闭:
Force Close
,Fatal
- 程序无响应:
Application Not Response
,ANR
(应用无响应)。一般是主线程超时无响应造成的。ANR
类型有:-
keyDispatchTimeout(Activity)
:5秒无响应-
位于
ActivityManagerService.java
类中// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
-
-
BroadcaseTimeout(Receiver)
:10秒无响应 -
ServiceTimeout(Service)
:20秒无响应
-
ANR
产生原因:- 在
UI
线程做了耗时操作。比如在Activity
中做了超过 5 秒无响应的耗时操作,比如文件读写,数据库读写,就会出现ANR
- 在
- ANR 避免:
- 不要在
UI
线程做耗时操作。
- 不要在
一. log
日志文件的位置
- 可以通过在
application
中实现接口:UncaughtExceptionHandler
, 在实现的 ·uncaughtException()· 方法中把产生的log
保存到本地。
二. log
日志文件的结构
三. log
日志中 bug
的查找和分析
-
日志文件关键字
Force Close
:Fatal
Application Not Response
:ANR
-
查看 Log 基本步骤
- 如果是
ANR
问题,在日志文件中搜索ANR
,快速定位到关键事件信息。 - 如果是
Force Close
或其他异常退出,搜索FATAL
,快速定位到关键事件信息。 - 定位到关键事件信息后,查看信息是否明确,如何不明确的话,查看具体的进程和线程跟踪的日志,来定位 bug
- 如果是
-
Force Close
快速定位案例-
出现了
Force Close
的情况,搜索关键字FATAL
,得到以下Log
。10-18 14:36:35.197 16078 16078 E AndroidRuntime: FATAL EXCEPTION: main 10-18 14:36:35.197 16078 16078 E AndroidRuntime: Process: cc.lijingbo.crashhandler, PID: 16078 10-18 14:36:35.197 16078 16078 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at cc.lijingbo.crashhandler.MainActivity$1.onClick(MainActivity.java:23) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.view.View.performClick(View.java:5232) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.view.View$PerformClick.run(View.java:21289) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.os.Looper.loop(Looper.java:168) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5885) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 10-18 14:36:35.197 16078 16078 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 10-18 14:36:35.207 1187 17570 E ActivityManager: App crashed! Process: cc.lijingbo.crashhandler 10-18 14:36:35.207 1187 17570 W ActivityManager: Force finishing activity cc.lijingbo.crashhandler/.MainActivity
-
看到因为
NullPointerException
造成的。
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.CharSequence android.widget.TextView.getText()' on a null object reference -
然后下一句提示项目的代码出错的地方:
at cc.lijingbo.crashhandler.MainActivity$1.onClick(MainActivity.java:23)
,在MainActivity
的onClick
方法的第23
行 -
源码
public class MainActivity extends AppCompatActivity {private TextView tv1; private TextView tv2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); tv1 = (TextView) findViewById(R.id.tv1); tv1.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this, tv2.getText().toString(), Toast.LENGTH_SHORT).show(); } }); } }
-
可以看到是因为使用
Toast
的时候,tv2
没有初始化,造成的空指针,把tv2
初始化就可以了。
-
-
ANR
快速定位案例
四. adb logcat
的学习和使用
- 抓取设备中日志到指定目录
- adb logcat >crash.log
参考:
Logcat 官网语法: https://developer.android.google.cn/studio/command-line/logcat.html#Syntax
Logcat 的使用:https://developer.android.google.cn/studio/debug/am-logcat.html
Analyze a Stack Trace: https://developer.android.google.cn/studio/debug/stacktraces.html
studio debug: https://developer.android.google.cn/studio/debug/index.html
如何分析解决 ANR : http://blog.csdn.net/dadoneo/article/details/8270107