Android高频面试专题 - 进阶篇(一)ANR

点击上方 Android扫地僧 ,选择 星标 公众号

重磅资源、干货分享,快上车!

ANR都回答不清楚,这个X没法装下去了。更多其他完整面试专题,请关注公众号获取。

1、什么是ANR

ANR:Application Not Responding,即应用无响应,Android系统对于一些事件需要在一定的时间范围内完成,如果超过预定时间能未能得到有效响应或者响应时间过长,都会造成ANR。一般地,这时往往会弹出一个提示框,告知用户当前xxx未响应,用户可选择继续等待或者Force Close。

2、ANR出现场景

Service Timeout:前台服务在20s内未执行完成,后台服务200s;

BroadcastQueue Timeout:前台广播在10s内未执行完成,后台广播60s

ContentProvider Timeout:内容提供者执行超时

InputDispatching Timeout: 输入事件分发超时5s,包括按键分发事件的超时。

3、ANR超时时间在哪定义

Service Timeout

文件:ActiveServices.java

// How long we wait for a service to finish executing.
static final int SERVICE_TIMEOUT = 20*1000; // 前台    // How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10; // 后台

Broadcast Timeout

文件:ActivityManagerService.java

// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_FG_TIMEOUT = 10*1000;  // 前台
static final int BROADCAST_BG_TIMEOUT = 60*1000;  // 后台
InputDispatching Timeout

文件:ActivityManagerService.java

// How long we wait until we timeout on key dispatching.
static final int KEY_DISPATCHING_TIMEOUT = 5*1000;

ContentProvider Timeout

// How long we wait for an attached process to publish its content providers
// before we decide it must be hung.
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;

4、ANR实现原理

主体实现在系统层,核心原理是消息调度和超时处理。经系统进程system_server调度,派发到应用进程完成对消息的实际处理,同时系统进程设计了不同的超时限制来跟踪消息的处理。一旦消息处理不当,则会触发超时限制,收集当前的系统状态,然后报告给用户有进程无响应。

Android系统ANR的实现,基本都是基于Handler消息机制来完成的。前面说过响应超时的定义,那么在一个事件执行开始时,通过Handler去post一个对应时间的延迟消息,如果事件在规定事件内执行完成,就remove掉这个message,否则,Handler就会收到这个ANR的Message,做进一步处理,dump日志,弹出ANR对话框。

在这里插入图片描述

5、ANR分析方法

traces.txt文件

应用ANR产生的时候,ActivityManagerService的appNotResponding方法就会被调用,然后在/data/anr/traces.txt文件中写入ANR相关信息.最新的ANR信息在最开始部分。

log分析

通常发生了ANR,ActivityManager会打印报错信息:ANR in com.xxx.xxxx // ANR出现的进程包名,从log中搜索“ANR in”或“am_anr”

6、traces文件位置,如何获取traces文件

在/data/anr/目录下

如果手机已经root,可以直接通过adb pull /data/anr/traces.txt d:/导出

没有root,网上其他方法基本都没用

通过adb bugreport E:\bugs导出(可行)

7、traces文件有哪些信息

ANR的进程id、时间和进程名称。

线程的基本信息

线程的优先级(默认5)、线程锁id和线程状态

线程的调用栈信息(这里可查看导致ANR的代码调用流程,分析ANR最重要的信息)

8、traces文件中线程的可能状态

ThreadState (defined at “dalvik/vm/thread.h “)
THREAD_UNDEFINED = -1, /* makes enum compatible with int32_t */
THREAD_ZOMBIE = 0, /* TERMINATED */( 线程死亡,终止运行)
THREAD_RUNNING = 1, /* RUNNABLE or running now */(线程可运行或正在运行)
THREAD_TIMED_WAIT = 2, /* TIMED_WAITING in Object.wait() */(执行了带有超时参数的wait、sleep或join函数)
THREAD_MONITOR = 3, /* BLOCKED on a monitor */(线程阻塞,等待获取对象锁)
THREAD_WAIT = 4, /* WAITING in Object.wait() */( 执行了无超时参数的wait函数)
THREAD_INITIALIZING= 5, /* allocated, not yet running */(新建,正在初始化,为其分配资源)
THREAD_STARTING = 6, /* started, not yet on thread list */(新建,正在启动)
THREAD_NATIVE = 7, /* off in a JNI native method */(正在执行JNI本地函数)
THREAD_VMWAIT = 8, /* waiting on a VM resource */(正在等待VM资源)
THREAD_SUSPENDED = 9, /* suspended, usually by GC or debugger */(线程暂停,通常是由于GC或debug被暂停)

9、可能导致ANR的原因

IO操作,如数据库、文件、网络

CPU不足,一般是别的App占用了大量的CPU,导致App无法及时处理

硬件操作,如camera

线程问题,如主线程被join/sleep,或wait锁等导致超时

Service问题,如service忙导致超时无响应,或service binder的数量达到上限

system server问题,如WatchDog发现ANR

10、哪些地方是执行在主线程的?

1.Activity的所有生命周期回调都是执行在主线程的.

2.Service默认是执行在主线程的.

3.BroadcastReceiver的onReceive回调是执行在主线程的.

4.没有使用子线程的Looper的Handler的handleMessage, post(Runnable)是执行在主线程的.

5.AsyncTask的回调中除了doInBackground, 其他都是执行在主线程的.

6.View的post(Runnable)是执行在主线程的.

11、日常开发中如何避免ANR

避免在主线程进行复杂耗时的操作,特别是文件读取或者数据库操作;

使用Thread或者HandlerThread时,调用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)设置优先级,否则仍然会降低程序响应,因为默认Thread的优先级和主线程相同。

避免频繁实时更新UI;

BroadCastReceiver 要进行复杂操作的的时候,可以在onReceive()方法中启动一个Service来处理;

避免在IntentReceiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。如果你的应用程序在响应Intent广 播时需要向用户展示什么,你应该使用Notification Manager来实现。

在设计及代码编写阶段避免出现出现同步/死锁或者错误处理不恰当等情况。

12、你开发中解决过的ANR问题

这个就需要各位老铁结合自己的实(fa)际(hui)经(xiang)验(xiang)来答复了,大部分人其实真实工作中是不会接触到ANR的,虽然有些东西只活在面试里,但是你也要会才行。


在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值