CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛
CXYVIP官网源码交易平台_网站源码_商城源码_小程序源码平台-丞旭猿论坛

Android应用ANR分析-源码交易平台丞旭猿

概述

当Android应用的UI线程被阻塞太久时,就会触发一个Application Not Responding(ANR)错误。如果APP运行在前台,系统就会弹出一个提示框,告知用户,用户可以选择继续等待或者强制关掉。

ANR的原因

ANR是因为负责更新UI的主线程无法处理用户输入事件或绘制操作,而导致的糟糕体验。

在Android中,程序的响应性是由Activity Manager与Window Manager系统服务来负责监控的,当系统检测到下面的条件之一时会显示ANR的对话框:

  • 对输入事件(例如硬件点击或者屏幕触摸事件),5秒内都无响应。
  • BroadcastReceiver不能在10秒内结束接收到的任务。

ANR的触发场景

  1. 在主线程执行耗时的IO操作。
  2. 在主线程执行耗时的计算。
  3. 在主线程与其他进程进行同步的binder调用,并且另一个进程需要很长时间才能返回。
  4. 主线程因等待其他线程的同步锁(synchronized)而被长时间阻塞。
  5. 主线程与另一个线程处于死锁状态。

检测ANR

Strict mode

使用StrictMode可以帮助你在开发的过程中发现在主线程意外的IO操作。

可以在Application、Activity或者其他应用组件进行配置:

publicvoidonCreate(){if(DEVELOPER_MODE){StrictMode.setThreadPolicy(newStrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork()// or .detectAll() for all detectable problems.penaltyLog().build());StrictMode.setVmPolicy(newStrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());}super.onCreate();}

允许后台ANR弹窗

默认情况下,Android只显示前台ANR弹窗,如果需要允许显示后台ANR弹窗,就要到开发者选项,开启Show all ANRs。

TraceView

使用Traceview去跟踪正在运行的应用,并定位主线程忙碌的位置。

分析traces日志文件

当发生ANR,Android系统会存储日志文件。日志路径:旧版系统:/data/anr/traces.txt新版系统:/data/anr/anr_*
publicclassMainActivityextendsAppCompatActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.btn_doANR).setOnClickListener(newView.OnClickListener(){@OverridepublicvoidonClick(Viewv){try{Thread.sleep(100000);}catch(InterruptedExceptione){e.printStackTrace();}}});}}

上面代码触发了ANR,相关日志:

"main"prio=5tid=1Sleeping|group="main"sCount=1dsCount=0flags=1obj=0x75115ec8self=0xeb674000|sysTid=10723nice=-10cgrp=defaultsched=0/0handle=0xf02fa494|state=Sschedstat=(38439814534829357257)utm=26stm=12core=2HZ=100|stack=0xff10b000-0xff10d000stackSize=8MB|heldmutexes=// Java调用堆栈信息,可以查看调用关系,定位到具体位置atjava.lang.Thread.sleep(Nativemethod)-sleepingon<0x02ed72b7>(ajava.lang.Object)atjava.lang.Thread.sleep(Thread.java:373)-locked<0x02ed72b7>(ajava.lang.Object)atjava.lang.Thread.sleep(Thread.java:314)atcom.github.xch168.anrdemo.MainActivity$1.onClick(MainActivity.java:18)// 触发ANR的方法atandroid.view.View.performClick(View.java:6597)atandroid.view.View.performClickInternal(View.java:6574)atandroid.view.View.access$3100(View.java:778)atandroid.view.View$PerformClick.run(View.java:25885)atandroid.os.Handler.handleCallback(Handler.java:873)atandroid.os.Handler.dispatchMessage(Handler.java:99)atandroid.os.Looper.loop(Looper.java:193)atandroid.app.ActivityThread.main(ActivityThread.java:6669)atjava.lang.reflect.Method.invoke(Nativemethod)atcom.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)

如何避免ANR

  1. 在工作线程中,执行耗时操作,如网络、DB操作或者Bitmap大小调整的操作。
  2. 使用AsyncTask来执行耗时操作。
  3. 使用线程或者HandlerThread,要通过Process.setThreadPriority()并传递THREAD_PRIORITY_BACKGROUND来设置线程的优先级为background,不然这个线程仍然会使得你的应用显得卡顿,因为这个线程默认与UI线程有着同样的优先级。
  4. 避免在BroadcastReceiver中执行耗时操作,如保存数据或者注册一个Notification。不能通过工作线程来执行复杂的任务操作,而应该启动一个IntentService来响应BroadcastReceiver中的长时间任务。

参考链接

  1. ANRs
  2. 避免出现程序无响应ANR
  3. Android应用ANR分析
  4. StrictMode
  5. ANR监测机制
  6. 理解Android ANR的触发原理
  7. Android ANR日志分析指南
  8. ANR 原理与实战技巧

声明:本文部分素材转载自互联网,如有侵权立即删除 。

© 版权声明
THE END
喜欢就支持一下吧
点赞0赞赏 分享
相关推荐
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容