Android ANR分析

本文详细介绍了Android ANR的产生原因,包括主线程和非主线程的ANR情况,以及如何分析ANR文件。重点讨论了SharedPreference的apply方法可能导致的ANR问题,并给出了ANR监控工具如ANR-WatchDog和BlockCanary。建议避免在主线程使用可能导致长时间阻塞的操作,以防止ANR发生。
摘要由CSDN通过智能技术生成

前言

ANR(Application Not Responding)即应用无响应,在Android系统中,应用发生的ANR由以下几种类型:

类型 说明
KeyDispatchTimeout 最常见的ANR类型是对输入事件5秒内无响应,比如按键或者触摸事件在此时间内无响应。
BroadcastTimeout BroadcastTimeout是在指定时间内(原生系统默认是10s)内无法处理完成,并且没有结束执行onReceive。
ServiceTimeout 这种类型在Android应用中出现的概率很小,是指Service在特定的时间(原生系统是20s)内无法处理完成。

引起ANR的根本原因总体来说有以下两种:

  • 应用程序本身逻辑有缺陷,或者在某些异常场景触发了此缺陷,如主线程堵塞、死锁循环等导致的。
  • 由于Android设备其他进程的CPU占用搞,导致当前应用进程无法抢占到CPU时间片。

主线程ANR的情况

  • 耗时网络操作。
  • 当有大量数据读写操作时再请求数据读写。
  • 数据库操作(比如其他大数据量应用访问数据库导致数据库负载过重时)。
  • 硬件操作(比如Camera)。
  • 调用thread_join() / Sleep() / Wait() 或者等待locker的时候。
  • Service binder数量达到上限。
  • Service忙导致超时无响应。

非主线程ANR的情况

  • 非主线程持有lock,导致主线程等待lock超时。
  • 非主线程终止或者崩溃导致主线程一直等待。

ANR文件介绍

在Android系统中,如果发生ANR,Logcat会产生对应的日志和一个trace文件,分析ANR的原因主要是分析这两个信息。trace文件在Android中的路径为/data/anr/traces.txt,可以使用adb来获取,adb pull /data/anr/traces.txt
  Logcat文件信息信息:

信息 说明
ANR IN 发生AND的具体类。
PID 发生ANR的进程,系统在此时会产生trace文件,当前的时间点也是发生ANR的具体时间,以及生成trace文件的时间。
Reason 当前ANR的类型以及导致ANR的原因。
CPU usage CPU的使用情况。

从Logcat中除了能看出在哪个类发生了ANR以及ANR的类型,具体的原因主要还是要看CPU的使用情况,如果CPU使用量很少,说明主线程可能堵塞,如果IOwait很高,说明ANR有可能是由于主线程进行耗时I/O操作造成的。

ANR文件分析

使用如下代码,模拟ANR:

public void onANR(View view) {
   
	Toast.makeText(this, "开始ANR模拟", Toast.LENGTH_SHORT).show();
	try {
   
		Thread.sleep(1000000);
	} catch (InterruptedException e) {
   
		e.printStackTrace();
	}
}

模拟结果如下:(注意:时间有点长,请耐心等待O(∩_∩)O)
ANR模拟演示

使用adb pull /data/anr/提取发生ANR之后生成的traces文件。

这里写图片描述

使用Android Studio上提供的一个分析traces文件的工具:Analyze Stacktrace。Analyze Stacktrace可以更加直观地分析导致ANR的工具。
  Analyze Stacktrace使用方法:

  1. 在Android Studio的工具栏中,选择Analyze->Analyze Stackstrace,打开Analyze Stackstrace工具窗口。
  2. 将traces.txt中的内容复制到窗口,单击Normalize按钮,生成Thread Dump列表,左边为所有线程列表,右边为选中线程的具体信息。

这里写图片描述

这里写图片描述

导致AND的信息为:

"main" prio=5 tid=1 Sleeping  | group="main" sCount=1 dsCount=0 obj=0x74239fa8 self=0x7f3e24897000  | sysTid=29044 nice=0 cgrp=apps sched=0/0 handle=0x7f3e27ba86a0  | state=S schedstat=( 0 0 0 ) utm=48 stm=43 core=0 HZ=100  | stack=0x7fff22dd1000-0x7fff22dd3000 stackSize=8MB  | held mutexes=
  at java.lang.Thread.sleep!(Native method)
  - sleeping on <0x1b893c4d> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:1031)
  - locked <0x1b893c4d> (a java.lang.Object)
  at java.lang.Thread.sleep(Thread.java:985)
  at link_work.myapplication.MainActivity.onANR(MainActivity.java:147)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)
  at android.view.View.performClick(View.java:4756)
  at android.view.View$PerformClick.run(View.java:19749)
  at android.os.Handler.handleCallback(Handler.java:739)
  at android.os.Handler.dispatchMessage(Handler.java:95)
  at android.os.Looper.loop(Looper.java:135)
  at android.app.ActivityThread.main(ActivityThread.java:5221)
  at java.lang.reflect.Method.invoke!(Native method)
  at java.lang.reflect.Method.invoke(Method.java:372)
  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

从上面的信息中at link_work.myapplication.MainActivity.onANR(MainActivity.java:147)可以看出问题发生在这里。主要原因是因为线程休眠的时间太长了,导致了ANR。

ANR监控

卡顿监控可以通过一个子线程向主线程发消息,通过时间差来判断是否发生卡顿。
ANR监控原理

ANR监控工具

引起ANR情况分析

引起ANR的情况有很多中,下面逐一分析。

Input系统—ANR

【Input系统—ANR原理分析】

说明 Log提示
无窗口, 有应用 Waiting because no window has focus but there is a focused application that may eventually add a window when it finishes starting up.
窗口暂停 Waiting because the [targetType] window is paused.
窗口未连接 Waiting because the [targetType] window’s input channel is not registered with the input dispatcher. The windo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值