Android面试中常问的ANR问题

1.ANR定义

Android应用的主线程处于阻塞状态的时间过长,触发"Application not Responding"(Anr)的错误.如果应用处于前台,会有弹窗.

2.ANR发生的原因

1.主线程耗时操作
2.主线程被子线程同步锁lock
3.主线程被binder对端阻塞
4.binder线程被沾满
5.得不到系统资源

3.ANR的几种类型

1.Service TimeOut超时
超时原因:
在执行服务的生命周期方法:oncreate ,onstart onbind的时候超时
超时时间: 前台服务20s,后台服务200s
2.BroadCast TimeOut广播超时
超时原因:
在指定的时间,onReceive方法执行超时
超时时间: 前台10s,后台60s
3.InputDispatching Timeout
输入事件超时,如点击,触摸事件无响应
超时时间:5s

ServiceTimeout触发机制

bumpServiceExecutingLocked();埋入炸弹,对应的生命周期在对应的时间内没有执行完,就会anr,如果处理完会removemsg
发送

 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
        if (proc.executingServices.size() == 0 || proc.thread == null) {
            return;
        }
        Message msg = mAm.mHandler.obtainMessage(
                ActivityManagerService.SERVICE_TIMEOUT_MSG);
        msg.obj = proc;
        mAm.mHandler.sendMessageDelayed(msg,
                proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
    }

处理SERVICE_TIMEOUT_MSG消息

com.android.server.am.ActivityManagerService#SERVICE_TIMEOUT_MSG
  case SERVICE_TIMEOUT_MSG: {
                mServices.serviceTimeout((ProcessRecord)msg.obj);
            } break;
//日志里的第一现场:Timeout executing service
Slog.w(TAG, "Timeout executing service: " + timeout);
StringWriter sw = new StringWriter();
PrintWriter pw = new FastPrintWriter(sw, false, 1024);
pw.println(timeout);
timeout.dump(pw, "    ");
pw.close();
mLastAnrDump = sw.toString();
mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
 anrMessage = "executing service " + timeout.shortInstanceName;

BroadCast Timeout 触发机制:

广播分为:串行,并行
引发超时的广播是串行广播:
动态注册的有序广播
静态注册广播

2.ANR定位流程

1.通过logcat查看ANR in 查看cpu信息和系统负载情况
apk包名,进程号,触发ANR的原因,系统在发生ANR的时间段的各个应用的cpu使用情况
如input超时,ANR根据超时时间,往前推5s,使用application is not responding过滤,过滤monkey日志

2.找到anr的log日志,检查主线程main的trace日志信息
/data/anr
3.定位发生ANR的具体时段
4.检查ANR发生时间段内系统的状态

3.避免ANR的方法:减少主线程耗时操作

1.ServiceTimeout
避免application oncreate耗时
避免service生命周期耗时
可以使用IntentService
2.BroadCastTimeout
可以使用IntentService
3.InputDispatching Timeout
避免主线程耗时

4.合理的性能优化也能够避免

1.避免while或ondraw 中new 对象
2.使用对象池 Android.util.Pools
3.检查多余的背景图片,特别是父布局的背景图片
4.减少布局层级:constrainlayout,merge
5.延时加载布局viewstub

4.ANR检测工具

blockcanary
strictmode
leakcanary

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zz白龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值