首先,我们简单写一个测试应用,手动制造一个ANR,代码如下


public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);anrTest();}private void anrTest() {Button anr_btn = findViewById(R.id.anr_btn);anr_btn.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {new Handler().post(new Runnable() {@Overridepublic void run() {String str="anr test";for (int i = 0; i <= 15000; i++) {str = str + i;if (i == 0 || i == 15000) {Log.d("MainActivity", "" + i);}}}});}});}
}

运行程序,点击anr_btn后,在多次点击button2,由于anr_btn再进行一个耗时的循环操作,导致button2的输入事件无法响应,从而产生ANR,界面如下

接下来我们分析anr/traces.txt文件,看看是不是由于耗时操作引起的UI线程被阻塞。打开Android Studio,点击右下角的Device File Explorer找到traces.txt,或者通过adb pull 导出来分析

查看trace.txt文件,开头即为产生anr的进程、时间及包名

----- pid 8428 at 1970-01-02 07:25:00 -----
Cmd line: com.psp.anrtest1

然后我们再看堆栈信息

"Jit thread pool worker thread 0" prio=5 tid=2 Native (still starting up)| group="" sCount=1 dsCount=0 obj=0x0 self=0x7f76e41400| sysTid=8433 nice=9 cgrp=default sched=0/0 handle=0x7f76509450| state=S schedstat=( 14509428 16964689 27 ) utm=1 stm=0 core=1 HZ=100| stack=0x7f7640b000-0x7f7640d000 stackSize=1021KB| held mutexes=kernel: __switch_to+0x7c/0x88kernel: futex_wait_queue_me+0xe4/0x160kernel: futex_wait+0xfc/0x210kernel: do_futex+0xdc/0x898kernel: SyS_futex+0x114/0x1a0kernel: el0_svc_naked+0x24/0x28native: #00 pc 000000000001c12c  /system/lib64/libc.so (syscall+28)native: #01 pc 00000000000e7ac8  /system/lib64/libart.so (_ZN3art17ConditionVariable16WaitHoldingLocksEPNS_6ThreadE+160)native: #02 pc 0000000000467d7c  /system/lib64/libart.so (_ZN3art10ThreadPool7GetTaskEPNS_6ThreadE+252)native: #03 pc 0000000000467238  /system/lib64/libart.so (_ZN3art16ThreadPoolWorker3RunEv+124)native: #04 pc 0000000000466b68  /system/lib64/libart.so (_ZN3art16ThreadPoolWorker8CallbackEPv+116)native: #05 pc 0000000000068470  /system/lib64/libc.so (_ZL15__pthread_startPv+196)native: #06 pc 000000000001ddc0  /system/lib64/libc.so (__start_thread+16)(no managed stack frames)"main" prio=5 tid=1 Runnable| group="main" sCount=0 dsCount=0 obj=0x753b8a10 self=0x7f76e40a00| sysTid=8428 nice=-10 cgrp=default sched=0/0 handle=0x7f7ae00a98| state=R schedstat=( 6123797127 320340821 21818 ) utm=186 stm=426 core=1 HZ=100| stack=0x7fcfc1c000-0x7fcfc1e000 stackSize=8MB| held mutexes= "mutator lock"(shared held) at com.psp.anrtest1.MainActivity$1$1.run(MainActivity.java:35)at android.os.Handler.handleCallback(Handler.java:751)at android.os.Handler.dispatchMessage(Handler.java:95)at android.os.Looper.loop(Looper.java:154)at android.app.ActivityThread.main(ActivityThread.java:6119)at java.lang.reflect.Method.invoke!(Native method)at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)"JDWP" daemon prio=5 tid=4 WaitingInMainDebuggerLoop| group="system" sCount=1 dsCount=0 obj=0x12c72ca0 self=0x7f76e42800| sysTid=8435 nice=0 cgrp=default sched=0/0 handle=0x7f7630b450| state=S schedstat=( 3374998 2467084 12 ) utm=0 stm=0 core=2 HZ=100| stack=0x7f76211000-0x7f76213000 stackSize=1005KB| held mutexes=kernel: __switch_to+0x7c/0x88kernel: poll_schedule_timeout+0x44/0x68kernel: do_select+0x4dc/0x534kernel: core_sys_select+0x208/0x324kernel: SyS_pselect6+0x18c/0x238kernel: el0_svc_naked+0x24/0x28native: #00 pc 000000000006a944  /system/lib64/libc.so (__pselect6+8)native: #01 pc 0000000000023430  /system/lib64/libc.so (select+156)native: #02 pc 0000000000552c20  /system/lib64/libart.so (_ZN3art4JDWP12JdwpAdbState15ProcessIncomingEv+340)native: #03 pc 0000000000303b4c  /system/lib64/libart.so (_ZN3art4JDWP9JdwpState3RunEv+920)native: #04 pc 0000000000303020  /system/lib64/libart.so (_ZN3art4JDWPL15StartJdwpThreadEPv+48)native: #05 pc 0000000000068470  /system/lib64/libc.so (_ZL15__pthread_startPv+196)native: #06 pc 000000000001ddc0  /system/lib64/libc.so (__start_thread+16)(no managed stack frames)

找到代码出错的位置 at com.psp.anrtest1.MainActivity$1$1.run(MainActivity.java:35)

查看代码,果真是for循环导致,为了确保猜测,我们打印一下for循环所在的线程,是不是主线程

new Handler().post(new Runnable() {@Overridepublic void run() { Log.d("MainActivity","thread name = "+Thread.currentThread().getName());String str="anr test";for (int i = 0; i <= 15000; i++) {str = str + i;if (i == 0 || i == 15000) {Log.d("MainActivity", "" + i);}}}});

输出如下:

01-02 08:02:38.504 8856-8856/com.psp.anrtest1 D/MainActivity: thread name = main

果然运行在主线程,我们做如下修改,使之运行在子线程

new Handler().post(new Runnable() {@Overridepublic void run() {Log.d("MainActivity","thread name = "+Thread.currentThread().getName()); new Thread(new Runnable() {@Overridepublic void run() {Log.d("MainActivity","sun thread name = "+Thread.currentThread().getName());String str="anr test";for (int i = 0; i <= 15000; i++) {str = str + i;if (i == 0 || i == 15000) {Log.d("MainActivity", "" + i);}}}}).start();}});

点击anr_btn,循环确实运行在子线程了

01-02 08:08:11.000 9207-9207/com.psp.anrtest1 D/MainActivity: thread name = main
01-02 08:08:11.001 9207-9343/com.psp.anrtest1 D/MainActivity: sun thread name = Thread-2

此时,无论我们怎么操作界面,都不会产生ANR了。之前一直不知道,原来new Handler().post()这个方法一直是运行在主线程的。

Android ANR分析实践(二):由输入事件无响应产生的ANR分析及解决相关推荐

  1. Android EditText缴获与监听输入事件

    Android EditText缴获与监听输入事件 Android EditText截获与监听输入事件 预期目标:如下图,输入框中每输入一个字符,下面的TextView可以迅速的显示出来输入框中的内容 ...

  2. Android View系列(二):事件分发机制源码解析

    概述 在介绍点击事件规则之前,我们需要知道我们分析的是MotionEvent,即点击事件,所谓的事件分发就是对MotionEvent事件的分发过程,即当一个MotionEvent生成以后,系统需要把这 ...

  3. Android 蓝牙 HID 键值收发-小概率无响应处理

    同学,别退出呀,我可是全网最牛逼的 Android 蓝牙分析博主,我写了上百篇蓝牙文章,请点击下面了解本专栏,进入本博主主页看看再走呗,一定不会让你后悔的,记得一定要去看主页置顶文章哦.​​​​​​​ ...

  4. 鸿蒙系统测试失败,ANR-WatchDog-ohos: 一个简单的监测程序,可检测到鸿蒙系统的 ANR(Application Not Response-应用程序无响应)错误并引发有意义的异常...

    ANR-WatchDog-ohos 一个简单的监测程序,可检测到鸿蒙系统的 ANR(Application Not Response-应用程序无响应)错误并引发有意义的异常 项目名称:ANR-Watc ...

  5. linux input输入子系统分析《二》:s3c2440的ADC简单驱动实例分析

    1      mini2440的ADC驱动实例 这节与输入子系统无关,出现在这里是因为后面的章节会讲到触摸屏输入子系统驱动,由于触摸屏也使用ADC,因此本节是为了说明ADC通过驱动代码是如何控制的. ...

  6. Android TextView设置自动识别的超链接字体颜色,及自身点击事件无响应的解决办法

    前言 我们在给TextView设置超链接的时候,可能最简单的,Android已经给出了一个非常的简单的做法就是: 在xml中设置: <!--all表示匹配所有,web表示匹配网址 --> ...

  7. android曲面屏点击事件无响应,都说曲面屏中看不中用,主要原因有四点,第三点是关键!...

    都说曲面屏中看不中用,主要原因有四点,第三点是关键! 2020-11-17 11:29:39 0点赞 0收藏 0评论 回归纯平屏幕的iPhone 12发布后,那些直屏党用户的呼声更高了,而上一次还是在 ...

  8. C# KeyDown事件无响应解决方法

    问题一描述:当新建一个窗体时,添加KeyDown事件后,会正常处理,但是当添加有控件时,比如Button,TextBox,不会触发窗体的KeyDown事件,也没有调用KeyDown事件的处理程序. 原 ...

  9. web页面事件无响应,元素点击不到

    有可能出现这种情况的原因就是:z-index属性设置成负值导致,点击页面时,获取不到焦点,无法触发事件. 转载于:https://www.cnblogs.com/chenjzblog/p/418609 ...

最新文章

  1. 在centos下启动nginx出现Failed to start nginx.service:unit not found
  2. 最新研究前线-深度推荐系统真的有效吗?
  3. scale html 浏览器,javascript中scale怎么使用?
  4. logstash 中multiline插件的用法
  5. Ubuntu安装并使用sogou输入法
  6. oracle 转成 mysql_oracle转mysql总结(转)
  7. 添加ejs后页面空白解决办法
  8. linux dev input使用消失_Linux驱动04 | 启动分析之根文件系统
  9. 分享一个NI软件卸载工具
  10. 中望3D2022弹簧的设计
  11. 【业务安全-04】万能用户名及万能密码实验
  12. UE4 蓝图事件调度器Event Dispatcher
  13. 10 种为React应用程序设计样式的方法
  14. ns-3脚本初识——WIFI无线网络:third脚本
  15. 随机数qqqqqqqqqq_rand()
  16. 安科瑞配电列头柜产品XXX数据中心案例分享
  17. 让学历见鬼去吧----20世纪最狂妄的校园演讲
  18. Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade问题和原因
  19. 哪个计算机软件可以探究小孔成像,探究小孔成像实验报告.doc
  20. JVM介绍与知识脉络梳理

热门文章

  1. java 静态内部类 实例化_内部类及静态内部类的实例化
  2. 计算机音乐 带你去旅行,网易云音乐《带你去旅行》热评
  3. 关于计算机互联网的英语小报图片,关于简洁好看的英语手抄报图片
  4. XMLSOAP应用简介
  5. 新闻系统(1)之模板机制
  6. 后书《乡村振兴战略下传统村落文化旅游设计》,交浅而言深者,愚也
  7. 新兴国家战略级安全话题-软件供应链安全
  8. VIM快捷键大全(附图片一张)
  9. linux部署pinpoint2.4.0
  10. 品牌策略:摈弃主流与大众,触及小众圈层