当前位置: 首页 > web >正文

【Android】制造一个ANR并进行简单分析

常见ANR的场景简述

  1. 输入事件超时(Input dispatching timed out)
    描述:这是用户最能直接感知的ANR,当用户点击屏幕、滑动列表、按下按键等输入事件发生后,如果应用的主线程在5秒内没有处理完这个事件,就会触发ANR。
    根本原因:主线程正在执行耗时操作。例如网络请求,大量文件读写操作,复杂计算,主线程等待锁,主线程的 IPC 调用(Binder调用)被阻塞,对方处理缓慢等。

  2. 服务生命周期超时(Timeout executing service)
    描述:当一个 Service 在其生命周期函数(如 onCreate(), onStartCommand(), onBind(), onUnbind(), onRebind())中执行了太多工作,超过了20秒,就会触发ANR。
    根本原因:将耗时逻辑放在了Service的生命周期方法中。

  3. 广播接收器超时(Timeout of broadcast Broadcast Record)
    描述:当一个 BroadcastReceiver 在其 onReceive() 方法中执行了太多工作,超过了10秒(前台广播)或60秒(后台广播,如 ACTION_BOOT_COMPLETED),就会触发ANR。
    重要特点:onReceive() 方法本身就是在主线程执行的!
    根本原因:在 onReceive() 中执行了耗时操作。例如在接收到网络变化、电量变化的广播后,直接在其中进行网络请求或大量逻辑处理。

  4. 内容提供者超时(Timeout publishing content providers)
    描述:当一个 ContentProvider 在执行查询(query)、插入(insert)、更新(update)、删除(delete)等操作时耗时过长,也会触发ANR。虽然官方没有明确给出超时时间,但它同样运行在调用者的线程(如果调用者是主线程,那就在主线程运行)。
    根本原因:在ContentProvider的方法中执行了低效的数据库操作或耗时逻辑,并且调用方是主线程。

  5. 其他可能导致或加剧ANR的场景
    CPU 被抢占:
    应用进程或系统处于高负载状态。如果CPU被其他进程(或你应用内的其他线程)占满,主线程即使只做很少的工作,也可能因为抢不到CPU时间片而无法及时响应。
    常见于:应用在执行大量后台任务、手机正在发热降频、多个应用在后台激烈竞争资源。
    主线程的 IPC 调用(Binder Call):
    主线程通过Binder机制调用系统服务或其他进程的方法(如 AccountManager.blockingGetAuthToken(), ContentResolver.query()),如果对方处理缓慢,主线程就会被阻塞等待。
    内存不足与频繁 GC:
    当系统内存严重不足时,垃圾回收(GC)会变得非常频繁。而 GC 执行时会暂停所有线程(包括主线程)。如果主线程因为频繁的GC而无法得到执行,也可能间接导致ANR。
    厂商定制系统(ROM)的后台限制:
    一些国内厂商的Android系统为了省电,会非常激进地限制后台应用的活动(如冻结进程、限制网络、限制唤醒),这可能会导致你的Service或广播接收器被延迟执行,从而在恢复时发生ANR。

制造一个ANR

新建一个项目MyApplication,并且新建一个MainActivity,设置一个按钮的点击事件:

    private fun setClickListener() {actionButton?.setOnClickListener {Thread.sleep(10 * 1000)Toast.makeText(this, "点击了按钮", Toast.LENGTH_LONG).show()}}

在点击事件中,使主线程sleep10s(理论上大于5s就行)。
最后,连续点击按钮两次以触发ANR。

ANR日志的获取

anr触发后立即在AS终端执行以下命令获取日志:

adb bugreport

执行后,所有的日志文件都会生成到项目根目录:
在这里插入图片描述
解压后文件结构如下(不同Android版本可能不同):
在这里插入图片描述
anr目录下的为trace文件,包含ANR发生时的一些线程信息,以及函数调用栈。
下面的文件是Locat日志信息,包含ANR原因、进程信息以及CPU的使用情况。

ANR分析:

首先,查看Locat日志,定位ANR类型。一般通过搜索“ANR in”来过滤日志,找到上次ANR发生时间点的日志:
在这里插入图片描述
根据报错Input dispatching timed out,我们知道是由于输入事件没有得到及时处理,导致出现了ANR。且CPU目前使用情况正常,也没有io操作等待。

接下来,查看trace文件,看一下具体的函数调用栈:
在这里插入图片描述
根据调用栈,我们可以看到问题就发生在我们的onClick方法中,且当前主线程处于sleep的状态。
最后,结合具体代码逻辑,得出结论:
用户点击按钮时,主线程处于sleep状态,导致点击事件没有得到及时的处理,最终导致了ANR。

http://www.xdnf.cn/news/20346.html

相关文章:

  • Kotlin中抽象类和开放类
  • 《从报错到运行:STM32G4 工程在 Keil 中的头文件配置与调试实战》
  • CRYPT32!ASN1Dec_SignedDataWithBlobs函数分析之CRYPT32!ASN1Dec_AttributesNC的作用是得到三个证书
  • 垃圾回收算法详解
  • 《sklearn机器学习——回归指标2》
  • Java内部类
  • 再读强化学习(动态规划)
  • 时隔4年麒麟重新登场!华为这8.8英寸新「手机」给我看麻了
  • 《Ceph集群数据同步异常的根因突破与恢复实践》
  • 深入剖析RocketMQ分布式消息架构:从入门到精通的技术全景解析
  • Ubuntu 文件权限管理
  • 【正则表达式】选择(Alternation)和分支 (Branching)在正则表达式中的使用
  • MySQL InnoDB 的锁机制
  • Chrome 插件开发入门:打造个性化浏览器扩展
  • 神经网络|(十八)概率论基础知识-伽马函数·下
  • Follow 幂如何刷屏?拆解淘宝闪购×杨幂的情绪共振品牌营销
  • Doris 消费kafka消息
  • 通过PXE的方式实现Ubuntu 24.04 自动安装
  • 版本管理系统与平台(权威资料核对、深入解析、行业选型与国产平台补充)
  • 50.4k Star!我用这个神器,在五分钟内搭建了一个私有 Git 服务器!
  • 小程序的project.private.config.json是无依赖文件,那可以删除吗?
  • Aspose.Words for .NET 25.7:支持自建大语言模型(LLM),实现更安全灵活的AI文档处理功能
  • 《LangChain从入门到精通》系统学习教材大纲
  • java基础学习(四):类 - 了解什么是类,类中都有什么?
  • 25年下载chromedriver.140
  • 项目必备流程图,类图,E-R图实例速通
  • 面试 TOP101 贪心专题题解汇总Java版(BM95 —— BM96)
  • 实力登榜!美创科技荣膺数说安全《2025中国网络安全企业100强》
  • IDEA中Transaction翻译插件无法使用,重新配置Transaction插件方法
  • 基于飞算JavaAI的在线图书借阅平台设计实现