Android 性能优化-ANR 的原因和解决方案

本文详细探讨了Android应用程序无响应(ANR)的原因,包括输入事件超时、BroadcastReceiver和Service的限制,以及ContentProvider的操作延迟。ANR的实现原理主要涉及系统如何检测和处理这些情况。解决ANR的方法包括分析ANR日志、使用DDMS的traceview、集成ANR-WatchDog库以及避免主线程阻塞。建议遵循不在主线程执行耗时操作的最佳实践。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、出现 ANR 的情况

满足下面的一种情况系统就会弹出 ANR 提示

  1. 输入事件(按键和触摸事件) 5s 内没被处理;
  2. BroadcastReceiver 的事件 ( onRecieve() 方法) 在规定时间内没处理完 (前台广播为 10s,后台广播为 60s);
  3. Service 前台 20s 后台 200s 未完成启动;
  4. ContentProvider 的 publish() 在 10s 内没进行完。

通常情况下就是主线程被阻塞造成的。

2、ANR 的实现原理

以输入无响应的过程为例(基于 9.0 代码):

最终弹出 ANR 对话框的位置是与 AMS 同目录的类 AppErrorshandleShowAnrUi() 方法。这个类用来处理程序中出现的各种错误,不只 ANR,强行 Crash 也在这个类中处理。

    // base/core/java/com/android/server/am/AppErrors.java
    void handleShowAnrUi(Message msg) {
   
   
        Dialog dialogToShow = null;
        synchronized (mService) {
   
   
            AppNotRespondingDialog.Data data = (AppNotRespondingDialog.Data) msg.obj;
            // ...

            Intent intent = new Intent("android.intent.action.ANR");
            if (!mService.mProcessesReady) {
   
   
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_FOREGROUND);
            }
            mService.broadcastIntentLocked(null, null, intent,
                    null, null, 0, null, null, null, AppOpsManager.OP_NONE,
                    null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */);

            boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值