一文道破ANR

6 阅读7分钟

Android ANR 触发原理详解

一、ANR 概述

┌─────────────────────────────────────────────────────────────────────┐
│                        ANR (Application Not Responding)              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  核心原理: 【埋炸弹】 → 【拆炸弹】 / 【炸弹爆炸】                    │
│                                                                      │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │                                                             │     │
│  │   系统发起请求          App 处理中             结果判定     │     │
│  │        │                    │                     │         │     │
│  │        ▼                    ▼                     ▼         │     │
│  │   ┌─────────┐          ┌─────────┐          ┌─────────┐    │     │
│  │   │ 埋炸弹  │────────► │ 处理中  │────────► │ 拆炸弹  │    │     │
│  │   │设置超时 │          │         │  及时完成 │ 移除超时│    │     │
│  │   └─────────┘          └─────────┘          └─────────┘    │     │
│  │        │                    │                               │     │
│  │        │                    │ 超时未完成                    │     │
│  │        │                    ▼                               │     │
│  │        │              ┌─────────┐                          │     │
│  │        └─────────────►│ 爆炸!   │                          │     │
│  │                       │ ANR触发 │                          │     │
│  │                       └─────────┘                          │     │
│  │                                                             │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

二、ANR 类型与超时时间

ANR 类型超时时间触发场景
Input ANR5 秒触摸、按键事件无响应
Broadcast ANR前台 10 秒 / 后台 60 秒广播接收器处理超时
Service ANR前台 20 秒 / 后台 200 秒Service 生命周期方法超时
ContentProvider ANR10 秒Provider 发布超时

三、Input ANR 原理

3.1 整体架构

┌─────────────────────────────────────────────────────────────────────┐
│                      Input ANR 检测架构                              │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│                        system_server 进程                            │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │                                                             │     │
│  │   InputReader              InputDispatcher                  │     │
│  │   (读取输入事件)           (分发输入事件)                   │     │
│  │        │                        │                           │     │
│  │        │                        │  ┌─────────────────────┐ │     │
│  │        └──────────────────────► │  │ ANR 超时检测        │ │     │
│  │                                 │  │                     │ │     │
│  │                                 │  │ - 记录发送时间      │ │     │
│  │                                 │  │ - 等待 App 回复     │ │     │
│  │                                 │  │ - 超时则触发 ANR    │ │     │
│  │                                 │  └─────────────────────┘ │     │
│  │                                 │           │               │     │
│  └─────────────────────────────────┼───────────┼───────────────┘     │
│                                    │           │                     │
│                     Socket 通信    │           │ 超时通知            │
│                                    ▼           ▼                     │
│                           ┌─────────────────────────┐               │
│                           │   App 进程               │               │
│                           │                         │               │
│                           │   UI Thread             │               │
│                           │   处理 Input 事件       │               │
│                           │   返回 "finished"       │               │
│                           │                         │               │
│                           └─────────────────────────┘               │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

3.2 InputDispatcher 检测机制

// frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp

// ANR 超时常量
constexpr std::chrono::nanoseconds DEFAULT_INPUT_DISPATCHING_TIMEOUT = 5s;

// 分发事件时开始计时
void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
                                           EventEntry* eventEntry,
                                           const std::vector<InputTarget>& inputTargets) {
    for (const InputTarget& inputTarget : inputTargets) {
        sp<Connection> connection = getConnectionLocked(inputTarget.inputChannel);

        // 发送事件给 App
        prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);

        // ════════════════════════════════════════════════════════
        // 【埋炸弹】记录等待开始时间
        // ════════════════════════════════════════════════════════
        connection->waitStartTime = currentTime;
    }
}

// 检查是否 ANR
void InputDispatcher::checkWindowAnrStateLocked(const sp<Connection>& connection) {
    nsecs_t currentTime = now();

    // 计算等待时间
    nsecs_t waitDuration = currentTime - connection->waitStartTime;

    // ════════════════════════════════════════════════════════
    // 超过 5 秒触发 ANR
    // ════════════════════════════════════════════════════════
    if (waitDuration > DEFAULT_INPUT_DISPATCHING_TIMEOUT) {
        onAnrLocked(connection);
    }
}

// App 处理完成后回调
void InputDispatcher::finishDispatchCycleLocked(nsecs_t finishTime,
                                                 const sp<Connection>& connection,
                                                 uint32_t seq, bool handled) {
    // ════════════════════════════════════════════════════════
    // 【拆炸弹】App 及时响应,清除等待状态
    // ════════════════════════════════════════════════════════
    connection->waitStartTime = LLONG_MAX;
}

3.3 Input ANR 流程图

┌─────────────────────────────────────────────────────────────────────┐
│                        Input ANR 触发流程                            │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  时间线 ─────────────────────────────────────────────────────────►  │
│       │                                                              │
│       │                                                              │
│  T0   │  用户触摸屏幕                                                │
│       │       │                                                      │
│       ▼       ▼                                                      │
│  ┌─────────────────────┐                                            │
│  │  InputReader        │  读取触摸事件                               │
│  │  从 /dev/input/     │                                            │
│  └──────────┬──────────┘                                            │
│             │                                                        │
│  T1         ▼                                                        │
│  ┌─────────────────────┐                                            │
│  │  InputDispatcher    │                                            │
│  │                     │                                            │
│  │  1. 找到目标窗口    │                                            │
│  │  2. 发送事件        │─────────────────────┐                      │
│  │  3. 记录发送时间    │  【埋炸弹】          │                      │
│  │     waitStartTime   │                     │                      │
│  └──────────┬──────────┘                     │                      │
│             │                                │                      │
│             │ 等待回复...                    ▼                      │
│             │                     ┌─────────────────────┐           │
│             │                     │  App UI Thread      │           │
│             │                     │                     │           │
│             │                     │  正常: 处理事件     │           │
│             │                     │  异常: 阻塞中...    │           │
│             │                     │       (Binder调用)  │           │
│             │                     │       (死循环)      │           │
│             │                     │       (锁等待)      │           │
│             │                     └─────────────────────┘           │
│             │                                │                      │
│     ┌───────┴───────┐                       │                      │
│     │               │                       │                      │
│  正常情况        异常情况                    │                      │
│     │               │                       │                      │
│     ▼               ▼                       │                      │
│  T < 5s          T > 5s                     │                      │
│     │               │                       │                      │
│  ┌──┴──┐       ┌────┴────┐                  │                      │
│  │收到  │       │未收到    │                  │                      │
│  │finish│       │finish   │                  │                      │
│  └──┬──┘       └────┬────┘                  │                      │
│     │               │                       │                      │
│     ▼               ▼                       │                      │
│ 【拆炸弹】      【爆炸!】                   │                      │
│  清除等待        触发ANR                     │                      │
│                     │                       │                      │
│                     ▼                       │                      │
│             ┌─────────────────────┐         │                      │
│             │  通知 AMS           │         │                      │
│             │  收集 ANR 信息      │         │                      │
│             │  弹出 ANR 对话框    │         │                      │
│             └─────────────────────┘         │                      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

四、Broadcast ANR 原理

4.1 广播处理流程

// frameworks/base/services/core/java/com/android/server/am/BroadcastQueue.java

public final class BroadcastQueue {

    // 超时时间常量
    static final int BROADCAST_FG_TIMEOUT = 10 * 1000;  // 前台广播 10秒
    static final int BROADCAST_BG_TIMEOUT = 60 * 1000;  // 后台广播 60秒

    // 处理有序广播
    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
        BroadcastRecord r;

        // 获取下一个待处理的广播
        r = mDispatcher.getNextBroadcastLocked(now);

        if (r != null) {
            // ════════════════════════════════════════════════════
            // 【埋炸弹】设置超时消息
            // ════════════════════════════════════════════════════
            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
            setBroadcastTimeoutLocked(timeoutTime);

            // 发送广播给接收者
            performReceiveLocked(r.callerApp, r.resultTo,
                    new Intent(r.intent), r.resultCode, r.resultData,
                    r.resultExtras, false, false, r.userId);
        }
    }

    // 设置超时
    final void setBroadcastTimeoutLocked(long timeoutTime) {
        if (!mPendingBroadcastTimeoutMessage) {
            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);
            // 发送延迟消息
            mHandler.sendMessageAtTime(msg, timeoutTime);
            mPendingBroadcastTimeoutMessage = true;
        }
    }

    // 广播处理完成
    public void finishReceiverLocked(BroadcastRecord r, int resultCode,
            String resultData, Bundle resultExtras, boolean resultAbort,
            boolean waitForServices) {

        // ════════════════════════════════════════════════════
        // 【拆炸弹】取消超时消息
        // ════════════════════════════════════════════════════
        cancelBroadcastTimeoutLocked();

        // 处理下一个广播
        processNextBroadcastLocked(false, false);
    }

    // 超时处理
    final void broadcastTimeoutLocked(boolean fromMsg) {
        // ════════════════════════════════════════════════════
        // 【爆炸】超时触发
        // ════════════════════════════════════════════════════

        long now = SystemClock.uptimeMillis();
        BroadcastRecord r = mDispatcher.getActiveBroadcastLocked();

        if (r != null && r.receiverTime > 0) {
            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;

            if (timeoutTime > now) {
                // 还没超时,重新设置
                setBroadcastTimeoutLocked(timeoutTime);
                return;
            }
        }

        // 真正超时,触发 ANR
        if (r != null) {
            mService.mAnrHelper.appNotResponding(r.curApp,
                    "Broadcast of " + r.intent.toString());
        }
    }
}

4.2 Broadcast ANR 时序图

┌─────────────────────────────────────────────────────────────────────┐
│                     Broadcast ANR 触发流程                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  AMS (BroadcastQueue)                  App (BroadcastReceiver)      │
│        │                                        │                    │
│        │                                        │                    │
│   T0   │ processNextBroadcast()                 │                    │
│        │                                        │                    │
│        │ ┌─────────────────────────────────┐   │                    │
│        │ │ 1. 获取下一个广播接收者          │   │                    │
│        │ │ 2. 【埋炸弹】                    │   │                    │
│        │ │    sendMessageAtTime(           │   │                    │
│        │ │      BROADCAST_TIMEOUT_MSG,     │   │                    │
│        │ │      now + 10s)                 │   │                    │
│        │ │ 3. 发送广播                     │   │                    │
│        │ └─────────────────────────────────┘   │                    │
│        │                                        │                    │
│        │ ─────────── 广播Intent ──────────────► │                    │
│        │                                        │                    │
│        │                                        │ onReceive() {      │
│        │                                        │   // 处理广播      │
│        │   等待完成...                          │   // 如果耗时操作  │
│        │                                        │   // 会导致超时    │
│        │                                        │ }                  │
│        │                                        │                    │
│  ┌─────┴─────────────────────────────┐         │                    │
│  │                                    │         │                    │
│  │  情况A: 10秒内完成                 │         │                    │
│  │                                    │         │                    │
│  │  ◄────────── finish ──────────────│─────────│                    │
│  │                                    │         │                    │
│  │  finishReceiverLocked()           │         │                    │
│  │    【拆炸弹】                      │         │                    │
│  │    cancelBroadcastTimeoutLocked() │         │                    │
│  │                                    │         │                    │
│  └────────────────────────────────────┘         │                    │
│                                                  │                    │
│  ┌─────────────────────────────────────────────┐│                    │
│  │                                              ││                    │
│  │  情况B: 超过10秒                             ││                    │
│  │                                              ││ (还在处理...)     │
│  │  Handler 收到 BROADCAST_TIMEOUT_MSG         ││                    │
│  │                                              ││                    │
│  │  broadcastTimeoutLocked()                   ││                    │
│  │    【爆炸!】                                ││                    │
│  │    appNotResponding()                       ││                    │
│  │                                              ││                    │
│  └─────────────────────────────────────────────┘│                    │
│                                                  │                    │
└─────────────────────────────────────────────────────────────────────┘

五、Service ANR 原理

5.1 Service 超时检测

// frameworks/base/services/core/java/com/android/server/am/ActiveServices.java

public final class ActiveServices {

    // 超时时间常量
    static final int SERVICE_TIMEOUT = 20 * 1000;      // 前台服务 20秒
    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10; // 后台 200秒

    // 启动服务时
    private void realStartServiceLocked(ServiceRecord r, ProcessRecord app,
            boolean execInFg) throws RemoteException {

        // ════════════════════════════════════════════════════
        // 【埋炸弹】设置超时
        // ════════════════════════════════════════════════════
        bumpServiceExecutingLocked(r, execInFg, "create");

        // 调用 App 的 onCreate
        app.thread.scheduleCreateService(r, r.serviceInfo,
                mAm.compatibilityInfoForPackage(r.serviceInfo.applicationInfo),
                app.getReportedProcState());
    }

    private void bumpServiceExecutingLocked(ServiceRecord r, boolean fg,
            String why) {

        long now = SystemClock.uptimeMillis();

        if (r.executeNesting == 0) {
            r.executingStart = now;

            // 计算超时时间
            long timeout = fg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT;

            // 发送延迟消息
            Message msg = mAm.mHandler.obtainMessage(
                    ActivityManagerService.SERVICE_TIMEOUT_MSG);
            msg.obj = r.app;
            mAm.mHandler.sendMessageDelayed(msg, timeout);

            r.app.executingServices.add(r);
        }
        r.executeNesting++;
    }

    // 服务方法执行完成
    private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
            boolean finishing) {

        r.executeNesting--;

        if (r.executeNesting == 0) {
            // ════════════════════════════════════════════════════
            // 【拆炸弹】取消超时消息
            // ════════════════════════════════════════════════════
            if (r.app != null) {
                mAm.mHandler.removeMessages(
                        ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
                r.app.executingServices.remove(r);
            }
        }
    }

    // 超时处理
    void serviceTimeout(ProcessRecord proc) {
        // ════════════════════════════════════════════════════
        // 【爆炸】触发 ANR
        // ════════════════════════════════════════════════════

        synchronized(mAm) {
            if (proc.executingServices.size() == 0) {
                return;  // 已经处理完了
            }

            long now = SystemClock.uptimeMillis();
            long maxTime = now -
                    (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);

            // 检查是否真正超时
            for (ServiceRecord sr : proc.executingServices) {
                if (sr.executingStart < maxTime) {
                    // 真正超时,触发 ANR
                    mAm.mAnrHelper.appNotResponding(proc,
                            "executing service " + sr.shortInstanceName);
                    return;
                }
            }
        }
    }
}

5.2 Service 生命周期与 ANR 检测

┌─────────────────────────────────────────────────────────────────────┐
│                     Service ANR 检测时机                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  以下 Service 生命周期方法都有超时检测:                             │
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                                                              │   │
│  │   onCreate()           ──────►  超时 20/200 秒              │   │
│  │        │                                                     │   │
│  │        ▼                                                     │   │
│  │   onStartCommand()     ──────►  超时 20/200 秒              │   │
│  │        │                                                     │   │
│  │        ▼                                                     │   │
│  │   onBind()             ──────►  超时 20/200 秒              │   │
│  │        │                                                     │   │
│  │        ▼                                                     │   │
│  │   onUnbind()           ──────►  超时 20/200 秒              │   │
│  │        │                                                     │   │
│  │        ▼                                                     │   │
│  │   onDestroy()          ──────►  超时 20/200 秒              │   │
│  │                                                              │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                      │
│  注意: 前台服务 20秒, 后台服务 200秒                                │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────┐
│                     Service ANR 时序图                               │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  AMS                                    App                          │
│   │                                      │                           │
│   │ realStartServiceLocked()             │                           │
│   │                                      │                           │
│   │ ┌──────────────────────────────┐    │                           │
│   │ │ bumpServiceExecutingLocked() │    │                           │
│   │ │ 【埋炸弹】                    │    │                           │
│   │ │ sendMessageDelayed(          │    │                           │
│   │ │   SERVICE_TIMEOUT_MSG, 20s)  │    │                           │
│   │ └──────────────────────────────┘    │                           │
│   │                                      │                           │
│   │ ─── scheduleCreateService() ──────► │                           │
│   │                                      │ ActivityThread            │
│   │                                      │ handleCreateService()     │
│   │                                      │      │                    │
│   │        等待...                       │      ▼                    │
│   │                                      │ service.onCreate()        │
│   │                                      │      │                    │
│   │                                      │      │ 【如果耗时】       │
│   │                                      │      │ 网络请求           │
│   │                                      │      │ 数据库操作         │
│   │                                      │      │ 复杂计算           │
│   │                                      │      │                    │
│   │                                      │      ▼                    │
│   │ ◄── serviceDoneExecutingLocked ──── │ (完成)                    │
│   │                                      │                           │
│   │ ┌──────────────────────────────┐    │                           │
│   │ │ 【拆炸弹】                    │    │                           │
│   │ │ removeMessages(              │    │                           │
│   │ │   SERVICE_TIMEOUT_MSG)       │    │                           │
│   │ └──────────────────────────────┘    │                           │
│   │                                      │                           │
│   ──────────────── OR ──────────────────                            │
│   │                                      │                           │
│   │ Handler 收到 SERVICE_TIMEOUT_MSG    │                           │
│   │ ┌──────────────────────────────┐    │ (还在处理...)             │
│   │ │ serviceTimeout()             │    │                           │
│   │ │ 【爆炸!】                    │    │                           │
│   │ │ appNotResponding()           │    │                           │
│   │ └──────────────────────────────┘    │                           │
│   │                                      │                           │
│   ▼                                      ▼                           │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

六、ContentProvider ANR 原理

// frameworks/base/services/core/java/com/android/server/am/ContentProviderHelper.java

final class ContentProviderHelper {

    static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10 * 1000;  // 10秒

    // 等待 Provider 发布
    private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, int callingUid, String callingPackage,
            String callingTag, boolean stable, int userId) {

        // 如果 Provider 还没启动,需要等待
        synchronized (cpr) {
            while (cpr.provider == null) {
                // ════════════════════════════════════════════════════
                // 【等待 Provider 发布,超时 10 秒】
                // ════════════════════════════════════════════════════
                long timeout = SystemClock.uptimeMillis() +
                        CONTENT_PROVIDER_PUBLISH_TIMEOUT;

                try {
                    cpr.wait(CONTENT_PROVIDER_PUBLISH_TIMEOUT);
                } catch (InterruptedException ex) {
                }

                if (cpr.provider == null &&
                        SystemClock.uptimeMillis() >= timeout) {
                    // 超时,触发 ANR
                    return null;
                }
            }
        }

        return cpr.newHolder(conn, false);
    }

    // App 发布 Provider
    void publishContentProviders(IApplicationThread caller,
            List<ContentProviderHolder> providers) {

        synchronized (cpr) {
            cpr.provider = src.provider;
            cpr.notifyAll();  // 唤醒等待的线程
        }
    }
}

七、ANR 信息收集与处理

7.1 ANR 处理流程

// frameworks/base/services/core/java/com/android/server/am/AnrHelper.java

class AnrHelper {

    void appNotResponding(ProcessRecord anrProcess, String annotation) {
        // 在单独线程中处理,避免阻塞
        AnrRecord anrRecord = new AnrRecord(anrProcess, annotation);
        mAnrRecords.add(anrRecord);

        // 启动处理线程
        startAnrConsumerIfNeeded();
    }

    private void processAnrRecord(AnrRecord record) {
        // 收集 ANR 信息
        ProcessRecord proc = record.mApp;

        // 1. Dump 主要进程的堆栈
        File tracesFile = ActivityManagerService.dumpStackTraces(
                firstPids, nativePids, extraPids, ...);

        // 2. 收集 CPU 使用信息
        updateCpuStatsNow();

        // 3. 写入 ANR 日志
        writeAnrToEventLog(proc, annotation);

        // 4. 显示 ANR 对话框 (或直接杀进程)
        if (showBackground || isInterestingForBackgroundTraces(proc)) {
            Message msg = mHandler.obtainMessage(SHOW_NOT_RESPONDING_UI_MSG);
            msg.obj = new AppNotRespondingDialog.Data(proc, annotation, ...);
            mHandler.sendMessage(msg);
        } else {
            // 后台进程直接杀死
            mService.mAppErrors.handleAppNotRespondingProcess(proc);
        }
    }
}

7.2 ANR 信息收集内容

┌─────────────────────────────────────────────────────────────────────┐
│                     ANR 信息收集内容                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  /data/anr/traces.txt (或 traces_*.txt)                             │
│  ┌────────────────────────────────────────────────────────────┐     │
│  │                                                             │     │
│  │  1. 进程信息                                                │     │
│  │     - 进程名、PID、UID                                      │     │
│  │     - ANR 类型和原因                                        │     │
│  │                                                             │     │
│  │  2. 主线程堆栈 (Main Thread)                                │     │
│  │     - 线程状态 (Running/Sleeping/Blocked/Waiting)          │     │
│  │     - 完整调用栈                                            │     │
│  │     - 锁信息 (held/waiting)                                 │     │
│  │                                                             │     │
│  │  3. 其他线程堆栈                                            │     │
│  │     - Binder 线程                                           │     │
│  │     - 工作线程                                              │     │
│  │     - AsyncTask 线程                                        │     │
│  │                                                             │     │
│  │  4. CPU 使用情况                                            │     │
│  │     - 各进程 CPU 占用                                       │     │
│  │     - iowait 情况                                           │     │
│  │                                                             │     │
│  │  5. 内存信息                                                │     │
│  │     - 进程内存使用                                          │     │
│  │     - 系统内存状态                                          │     │
│  │                                                             │     │
│  └────────────────────────────────────────────────────────────┘     │
│                                                                      │
│  其他日志:                                                           │
│  - /data/system/dropbox/  (压缩的ANR信息)                           │
│  - logcat 中的 ANR 信息                                             │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

八、完整 ANR 触发时序总结

┌─────────────────────────────────────────────────────────────────────┐
│                     ANR 完整触发时序                                 │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│   System Server                                    App               │
│        │                                            │                │
│        │                                            │                │
│   ═════╪════════════════════════════════════════════╪═══════════    │
│   阶段1│【埋炸弹】                                  │                │
│   ═════╪════════════════════════════════════════════╪═══════════    │
│        │                                            │                │
│        │  发起请求 (Input/Broadcast/Service...)     │                │
│        │────────────────────────────────────────────►                │
│        │                                            │                │
│        │  设置超时定时器                            │                │
│        │  Handler.sendMessageDelayed()             │                │
│        │  或 记录等待开始时间                       │                │
│        │                                            │                │
│        │                                            │                │
│   ═════╪════════════════════════════════════════════╪═══════════    │
│   阶段2│【处理中】                                  │                │
│   ═════╪════════════════════════════════════════════╪═══════════    │
│        │                                            │                │
│        │                                            │ 执行任务       │
│        │                                            │ (可能阻塞)     │
│        │       等待回复...                          │    │           │
│        │                                            │    │           │
│        │                                            │    │           │
│   ═════╪════════════════════════════════════════════╪════╪══════    │
│   阶段3│【结果判定】                                │    │           │
│   ═════╪════════════════════════════════════════════╪════╪══════    │
│        │                                            │    │           │
│    ┌───┴────────────────────────────────────────────┴────┴───┐      │
│    │                                                          │      │
│    │  路径A: 及时完成                路径B: 超时              │      │
│    │     │                              │                     │      │
│    │     ▼                              ▼                     │      │
│    │  收到完成回调                   定时器触发               │      │
│    │     │                              │                     │      │
│    │     ▼                              ▼                     │      │
│    │  【拆炸弹】                     【爆炸!】               │      │
│    │  取消定时器                     ANR 触发                 │      │
│    │  正常继续                          │                     │      │
│    │                                    ▼                     │      │
│    │                              收集信息:                   │      │
│    │                              - dump traces               │      │
│    │                              - CPU 使用                  │      │
│    │                              - 内存状态                  │      │
│    │                                    │                     │      │
│    │                                    ▼                     │      │
│    │                              显示 ANR 对话框             │      │
│    │                              或杀死进程                  │      │
│    │                                                          │      │
│    └──────────────────────────────────────────────────────────┘      │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

九、各类 ANR 对比总结

┌─────────────────────────────────────────────────────────────────────┐
│                        ANR 类型对比                                  │
├────────────┬─────────────┬────────────────┬────────────────────────┤
│  类型      │  超时时间    │   检测位置      │   触发条件             │
├────────────┼─────────────┼────────────────┼────────────────────────┤
│            │             │                │                        │
│  Input5 秒      │ InputDispatcher│  Input事件未及时       │
│  ANR       │             │ (native层)     │  返回 "finished"       │
│            │             │                │                        │
├────────────┼─────────────┼────────────────┼────────────────────────┤
│            │  前台 10秒  │                │                        │
│  Broadcast │             │ BroadcastQueue │  onReceive() 未及时    │
│  ANR       │  后台 60秒  │ (Java层)       │  完成                  │
│            │             │                │                        │
├────────────┼─────────────┼────────────────┼────────────────────────┤
│            │  前台 20秒  │                │                        │
│  Service   │             │ ActiveServices │  生命周期方法未及时    │
│  ANR       │  后台 200秒 │ (Java层)       │  完成                  │
│            │             │                │                        │
├────────────┼─────────────┼────────────────┼────────────────────────┤
│            │             │ ContentProvider│                        │
│  Provider  │   10 秒     │ Helper         │  Provider 发布超时     │
│  ANR       │             │ (Java层)       │                        │
│            │             │                │                        │
└────────────┴─────────────┴────────────────┴────────────────────────┘

十、关键要点

┌─────────────────────────────────────────────────────────────────────┐
│                         核心要点                                     │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  1. ANR 本质是【超时检测机制】                                       │
│     - 系统发起请求时设置超时定时器 (埋炸弹)                         │
│     - App 及时完成则取消定时器 (拆炸弹)                             │
│     - 超时未完成则触发 ANR (爆炸)                                   │
│                                                                      │
│  2. 检测发生在【系统侧】,不是 App 侧                               │
│     - InputDispatcher 检测 Input ANR                                │
│     - AMS 检测 Broadcast/Service/Provider ANR                       │
│                                                                      │
│  3. 【主线程阻塞】是根本原因                                         │
│     - Binder 同步调用                                               │
│     - 锁等待 (synchronized/Lock)                                    │
│     - 死循环或复杂计算                                              │
│     - IO 操作 (网络/数据库/文件)                                    │
│                                                                      │
│  4. 预防措施                                                         │
│     - 主线程只做 UI 相关轻量操作                                    │
│     - 耗时操作放到工作线程                                          │
│     - 避免主线程锁竞争                                              │
│     - 使用 StrictMode 检测                                          │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘