You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android应用ANR率过高:如何从崩溃报告定位Input dispatching timed out根源?

Android 12/13 ANR(Input dispatching timed out)排查与解决思路

一、定位主线程阻塞根源

  • 抓取ANR现场的traces文件:系统触发ANR时会在/data/anr/traces.txt生成调用栈日志,通过adb pull /data/anr/traces.txt导出。文件会明确显示主线程被哪个任务占用,直接锁定违规代码。
  • 启用StrictMode强制检测:在RunnerActivity的onCreate中添加配置,捕获主线程的磁盘IO(含SQLite操作):
    if (BuildConfig.DEBUG) {
        StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
                .detectDiskReads()
                .detectDiskWrites()
                .penaltyLog()
                .penaltyDeath()
                .build());
    }
    
    调试阶段只要主线程执行SQL,就会抛出异常或打印详细日志,快速定位问题代码。

二、优化SQL查询与任务调度

  • 所有SQL操作移至后台线程:用Coroutine(Kotlin)、ExecutorService或WorkManager执行查询,绝对禁止主线程操作数据库。
  • 合并批量小查询:将多个独立小查询合并为单条复杂查询(如JOIN、子查询),减少数据库IO次数。
  • 优化SQL与索引:用EXPLAIN QUERY PLAN分析慢查询,给频繁过滤、排序的字段加索引,避免全表扫描。示例:
    EXPLAIN QUERY SELECT * FROM reports WHERE date BETWEEN ? AND ?;
    
  • 控制查询并发数:线程池执行查询时,限制核心线程数(如按CPU核心数设4-8个),避免过多并发引发数据库锁竞争,间接阻塞主线程。

三、Android 12/13适配优化

  • 合规使用后台任务:若报告生成依赖后台服务,需申请POST_NOTIFICATIONS权限,启动服务时调用startForeground()显示通知,避免系统限制任务执行。
  • 拆分主线程UI操作:后台查询完成后,若需处理大量数据再渲染UI,采用分页加载、异步解析,避免一次性在主线程处理海量数据导致阻塞。

四、补充日志与监控

  • 添加关键节点日志:在数据库操作的入口、出口记录执行时间与SQL语句,结合ANR时间点匹配耗时最长的查询:
    Log.d("DB", "Start query: " + sql);
    long start = System.currentTimeMillis();
    Cursor cursor = db.rawQuery(sql, args);
    long end = System.currentTimeMillis();
    Log.d("DB", "Query finished, cost: " + (end - start) + "ms");
    
  • 用Android Studio Profiler监控:实时观察主线程CPU占用、任务队列,测试报告生成时,定位主线程的长时间阻塞任务。

内容的提问来源于stack exchange,提问作者Suresh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 05:35:27