android程序中,产生ANR原因与分析解决

news2025/1/17 3:03:15

产生原因

在android程序中,所有的输入(key和touch等)事件是由底层的InputDispatcher分发到上层的InputManagerService的,再通过InputManagerService内部的InputMonitor送入WindowManagerService的Policy(PhoneWindowManager)中。整个流程可以参考事件在native和jni中的流程和事件在java framework中的流程。而在事件分发的过程中,如果应用程序不能及时响应,就会产生ANR。

ANR的发生的场景

  • service timeout:前台服务在20s未执行完,后台服务200s未执行完。
  • BroadcastQueue timeout:前台广播在10s未执行完,后台广播在60s未执行完。
  • ContentProvider timeout: ContentProvider在发布时超过10s未执行完。
  • InputDispatching Timeout:输入分发事件超过5s未执行完。

ANR的过程总体就是:装炸弹、拆炸弹、引爆炸弹。

产生 ANR 需要满足以下条件,

  1. 只有应用程序进程的主线程(UI 线程)响应超时才会产生 ANR。
  2. 只有达到超时时间才能触发 ANR。产生 ANR 的上下文不同,超时时间也会不同。
  3. 只有输入事件或特定操作才能触发 ANR。输入事件是指按键、触屏等设备输入事件,特定操作是指 BroadcastReceiver 和 Service 的生命周期中的各个函数。产生 ANR 的上下文不同,导致 ANR 的原因也会不同。

ANR分析办法

ANR重现

这里使用的是号称Google亲儿子的Google Pixel xl(Android 8.0系统)做的测试,生成一个按钮跳转到ANRTestActivity,在后者的onCreate()中主线程休眠20秒:

@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_anr_test);    // 这是Android提供线程休眠函数,与Thread.sleep()最大的区别是    // 该使用该函数不会抛出InterruptedException异常。    SystemClock.sleep(20 * 1000);}

在进入ANRTestActivity后黑屏一段时间,大概有七八秒,终于弹出了ANR异常。

ANR分析办法一:Log

刚才产生ANR后,看下Log:

可以看到logcat清晰地记录了ANR发生的时间,以及线程的tid和一句话概括原因:WaitingInMainSignalCatcherLoop,大概意思为主线程等待异常。 最后一句The application may be doing too much work on its main thread.告知可能在主线程做了太多的工作。

ANR分析办法二:traces.txt

刚才的log有第二句Wrote stack traces to ‘/data/anr/traces.txt’,说明ANR异常已经输出到traces.txt文件,使用adb命令把这个文件从手机里导出来:

  • cd到adb.exe所在的目录,也就是Android SDK的platform-tools目录,例如:
cd D:\Android\AndroidSdk\platform-tools

此外,除了Windows的cmd以外,还可以使用AndroidStudio的Terminal来输入adb命令。

  • 到指定目录后执行以下adb命令导出traces.txt文件:
adb pull /data/anr/traces.txt

traces.txt默认会被导出到Android SDK的\platform-tools目录。一般来说traces.txt文件记录的东西会比较多,分析的时候需要有针对性地去找相关记录。

----- pid 23346 at 2017-11-07 11:33:57 -----  ----> 进程id和ANR产生时间Cmd line: com.sky.myjavatestBuild fingerprint: 'google/marlin/marlin:8.0.0/OPR3.170623.007/4286350:user/release-keys'ABI: 'arm64'Build type: optimizedZygote loaded classes=4681 post zygote classes=106Intern table: 42675 strong; 137 weakJNI: CheckJNI is on; globals=526 (plus 22 weak)Libraries: /system/lib64/libandroid.so /system/lib64/libcompiler_rt.so /system/lib64/libjavacrypto.so/system/lib64/libjnigraphics.so /system/lib64/libmedia_jni.so /system/lib64/libsoundpool.so/system/lib64/libwebviewchromium_loader.so libjavacore.so libopenjdk.so (9)Heap: 22% free, 1478KB/1896KB; 21881 objects    ----> 内存使用情况 ... "main" prio=5 tid=1 Sleeping    ----> 原因为Sleeping  | group="main" sCount=1 dsCount=0 flags=1 obj=0x733d0670 self=0x74a4abea00  | sysTid=23346 nice=-10 cgrp=default sched=0/0 handle=0x74a91ab9b0  | state=S schedstat=( 391462128 82838177 354 ) utm=33 stm=4 core=3 HZ=100  | stack=0x7fe6fac000-0x7fe6fae000 stackSize=8MB  | held mutexes=  at java.lang.Thread.sleep(Native method)  - sleeping on <0x053fd2c2> (a java.lang.Object)  at java.lang.Thread.sleep(Thread.java:373)  - locked <0x053fd2c2> (a java.lang.Object)  at java.lang.Thread.sleep(Thread.java:314)  at android.os.SystemClock.sleep(SystemClock.java:122)  at com.sky.myjavatest.ANRTestActivity.onCreate(ANRTestActivity.java:20) ----> 产生ANR的包名以及具体行数  at android.app.Activity.performCreate(Activity.java:6975)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)  at android.app.ActivityThread.-wrap11(ActivityThread.java:-1)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)  at android.os.Handler.dispatchMessage(Handler.java:105)  at android.os.Looper.loop(Looper.java:164)  at android.app.ActivityThread.main(ActivityThread.java:6541)  at java.lang.reflect.Method.invoke(Native method)  at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

在文件中使用 ctrl + F 查找包名可以快速定位相关代码。 通过上方log可以看出相关问题:

  • 进程id和包名:pid 23346 com.sky.myjavatest
  • 造成ANR的原因:Sleeping
  • 造成ANR的具体行数:ANRTestActivity.java:20类的第20行

特别注意:产生新的ANR,原来的 traces.txt 文件会被覆盖。

ANR分析办法三:Java线程调用分析

通过JDK提供的命令可以帮助分析和调试Java应用,命令为:

jstack {pid}

其中pid可以通过jps命令获得,jps命令会列出当前系统中运行的所有Java虚拟机进程,比如

7266 Test7267 Jps

ANR分析办法四:DDMS分析ANR问题

  • 使用DDMS——Update Threads工具
  • 阅读Update Threads的输出

造成ANR的原因及解决办法

上面例子只是由于简单的主线程耗时操作造成的ANR,造成ANR的原因还有很多:

  • 主线程阻塞或主线程数据读取

解决办法:避免死锁的出现,使用子线程来处理耗时操作或阻塞任务。尽量避免在主线程query provider、不要滥用SharePreferenceS

  • CPU满负荷,I/O阻塞

解决办法:文件读写或数据库操作放在子线程异步操作。

  • 内存不足

解决办法:AndroidManifest.xml文件中可以设置 android:largeHeap=“true”,以此增大App使用内存。不过不建议使用此法,从根本上防止内存泄漏,优化内存使用才是正道。

  • 各大组件ANR

各大组件生命周期中也应避免耗时操作,注意BroadcastReciever的onRecieve()、后台Service和ContentProvider也不要执行太长时间的任务。

防止产生 ANR 的方法主要就是避免在主线程中执行耗时的操作,可以降耗时操作放入子线程中执行。耗时操作包括:

  • 数据库操作。 数据库操作尽量采用异步方法做处理
  • 初始化的数据和控件太多
  • 频繁的创建线程或者其它大对象;
  • 加载过大数据和图片;
  • 对大数据排序和循环操作;
  • 过多的广播和滥用广播;
  • 大对象的传递和共享;
  • 网络操作

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/980420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux CentOS7设置时区

在Linux系统中&#xff0c;默认使用的是UTC时间。 即使在安装系统的时候&#xff0c;选择的时区是亚洲上海&#xff0c;Linux默认的BIOS时间&#xff08;也称&#xff1a;硬件时间&#xff09;也是UTC时间。 在重启之后&#xff0c;系统时间会和硬件时间同步&#xff0c;如果…

C# 命令行参数分割

CommandLineToArgvW 函数 [DllImport("shell32.dll", SetLastError true)] private static extern IntPtr CommandLineToArgvW([MarshalAs(UnmanagedType.LPWStr)] string lpCmdLine, out int pNumArgs); 参数&#xff1a; [in] lpCmdLine 类型&#xff1a;…

VR数字工厂,为企业工厂打造竞争新优势

工业经济中大部分行业都是制造业&#xff0c;为了合力助推工业经济提质增效&#xff0c;谋划推进制造业数字化转型就显得尤为重要了。用VR赋能工厂数字升级&#xff0c;打造VR数字工厂&#xff0c;满足各行各业沉浸式营销展示需求。 VR数字工厂是一种全新的工业模式&#xff0c…

淘宝天猫1688京东商品详情(PC端和APP端)数据代码如下

淘宝天猫1688京东商品详情&#xff08;PC端和APP端&#xff09;数据代码如下&#xff1a; 请求示例 # coding:utf-8 """ Compatible for python2.x and python3.x requirement: pip install requests """ from __future__ import print_functio…

大厂常用的B端设计系统推荐

伴随着企业级应用的迅速发展&#xff0c;越来越多的企业和组织开始关注设计系统&#xff0c;以提高其应用的设计效率和质量。B端设计系统在这一领域发挥着重要作用。本文将介绍8个著名的B端设计系统。开发者需要仔细分析自己的项目特点&#xff0c;了解每一个设计系统的特点和优…

登录密码加盐处理方式

哈喽&#xff01;大家好&#xff0c;我是旷世奇才李先生 文章持续更新&#xff0c;可以微信搜索【小奇JAVA面试】第一时间阅读&#xff0c;回复【资料】更有我为大家准备的福利哟&#xff0c;回复【项目】获取我为大家准备的项目 文章目录 一、登录密码加盐处理方式1、简介2、密…

Linux内核的GPIO子系统驱动框架详解

目录 1 引入 2 GPIO子系统的层次 3 gpio子系统驱动程序流程 4 gpio子系统的中药数据结构 5 gpio子系统函数调用的详细细节 6 GPIO子系统的sysfs接口 6.1有哪些gpio控制器 6.2每个gpio控制器的详细信息 6.3查看gpio使用情况 6.4通过SYSFS使用GPIO 6.4.1 确定GPIO编号…

Hadoop的第二个核心组件:MapReduce框架第一节

Hadoop的第二个核心组件&#xff1a;MapReduce框架第一节 一、基本概念二、MapReduce的分布式计算核心思想三、MapReduce程序在运行过程中三个核心进程四、如何编写MapReduce计算程序&#xff1a;&#xff08;编程步骤&#xff09;1、编写MapTask的计算逻辑2、编写ReduceTask的…

Linux命令行

目录 CLI GUI 命令行界面 图形界面 命令行提示符 # $ ​编辑 命令一般由三个部分组成 历史命令&#xff0c;使用上下键&#xff0c;或者使用history&#xff0c;ctrlr搜索历史命令 通配符 *,? 切换用户 su 作业管理 &&#xff0c;jobs,bg,fg CLI GUI 命令行界面 …

基于SSM的健身房管理系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

第一天 关于项目遇到的问题和缺少的知识点

1.配置静态资源映射 配置文件使用的都是配置类方式 创建配置类WebMvcConfig,设置静态资源映射 用于在Springboot项目中, 默认静态资源的存放目录为 : "classpath:/resources/", "classpath:/static/", "classpath:/public/" ; 而在我们的项目中静…

黑客是如何“免费”坐飞机的?

对于爱好飞行的“空中飞人”来说&#xff0c;航空里程早已不是什么新鲜话题。如何利用航司的各种会员等级福利&#xff1f;如何积累里程&#xff1f;如何兑换航线&#xff1f;这些与里程相关的研究和分析&#xff0c;甚至发展成了非常成熟的社区文化。 航空里程也在不断的发展…

AI云服务平台大全:GPU租用 | App托管 | MLOps平台

我们搜集整理了国内外主要的深度学习云服务商&#xff0c;包括云GPU供应商、WebApp托管商和MLOps平台商。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 1、云GPU供应商 只有一台笔记本电脑&#x1f4bb;不足以运行你的AI模型&#xff0c;忘记它吧&#xff0c;使用云 …

【网易云信】音画同步测试方法的研究与实践

概述 随着移动互联网的普及和网络带宽的提高&#xff0c;音视频通话越来越成为人们生活和工作中不可或缺的一部分。音画同步是音视频体验的一个重要指标&#xff0c;在音视频传输过程中&#xff0c;由于不同的传输策略因为网络的干扰&#xff0c;音频和视频往往难以同时到达&a…

智能小车—PWM方式实现小车调速和转向

目录 1. 让小车动起来 2. 串口控制小车方向 3. 如何进行小车PWM调速 4. PWM方式实现小车转向 1. 让小车动起来 电机模块开发 L9110s概述 接通VCC&#xff0c;GND 模块电源指示灯亮&#xff0c; 以下资料来源官方&#xff0c;具体根据实际调试 IA1输入高电平&#xff0c…

上海控安SmartRocket系列产品推介(六):SmartRocket PeneX汽车网络安全测试系统

产品概述 上海控安汽车网络安全测试系统PeneX&#xff08;Penetrator X&#xff09;是一款支持对整车及车辆零部件及子系统实施网络安全测试的系统&#xff0c;其包含硬件安全、软件系统安全、车内通信及车外通信四大安全测试系统&#xff1b;支持合规性测试&#xff0c;包含国…

《TCP/IP网络编程》阅读笔记--基于 TCP 的半关闭

目录 1--基于TCP的半关闭 1-1--TCP单方面完全断开的问题 1-2--shutdown()函数 1-3--半关闭的必要性 2--基于半关闭的文件传输程序 1--基于TCP的半关闭 1-1--TCP单方面完全断开的问题 Linux 系统中的 close 函数会将 TCP Socket 的连接完全断开&#xff0c;这意味着不能收…

项目(智慧教室)第四部分,页面交互功能

一。页面构思 1.标题栏 大标题&#xff1a;智慧教室管理系统 小标题&#xff1a;灯光&#xff0c;报警&#xff0c;风扇&#xff0c;温度&#xff0c;湿度&#xff0c;光照 2.样式设计 背景设置。字体设置&#xff08;字体大小&#xff0c;格式&#xff0c;颜色&#xff09; 3.…

算法之双指针题型:

双指针例题小总结&#xff1a; 力扣27&#xff1a; 移除元素 力扣题目链接 双指针分为&#xff1a; 快慢双指针&#xff1a;同一个起点&#xff0c;同向出发 相向双指针&#xff1a;从两端出发&#xff0c;方向相反&#xff0c;终会相遇 经典的双指针&#xff08;快慢双指…

ESP32用作经典蓝牙串口透传模块与手机进行串口通信

ESP32用作经典蓝牙串口透传模块与手机进行串口通信 简介ESP32开发板Arduino程序手机与ESP32开发板进行蓝牙串口透传通信总结 简介 ESP32-WROOM-32模组集成了双模蓝牙包括传统蓝牙&#xff08;BR/EDR&#xff09;、低功耗蓝牙&#xff08;BLE&#xff09;和 Wi-Fi&#xff0c;具…