1. 什么是ANR
Appliction Not Responding 直译过来的意思就是应用程序没有响应
  1. ANR的产生原因, 及场景
原因: 在UI线程上执行一个潜在的耗时操作场景:1.KeyDipatchTimeout(5 seconds)-->按键或触摸事件在特定时间内没有响应2.BroadcastReceiver(10 seconds)-->在特定时间内无法处理完成3.ServiceTimeout(20 seconds)-->service在特定时间内没有完成
  1. 如何监测ANR
原理:Android应用程序的所有交互操作和响应,都是通过主线程的消息机制来进行的。例如当用户点击了某个Button,系统会向主线程发送消息,主线程的Looper从主线程消息队列中取出消息并处理,处理完当前消息,主线程Looper再去取出下一个消息。当主线程做了耗时的任务,主线程的Looper就无法从消息队列中取出新的消息,所表现出的就是程序卡顿,甚至是ANR。同理,我们在子线程往主线程发送一个消息,要是消息无法得到及时处理,那说明程序发生ANR了。思路:在子线程里向主线程发消息,如果过了固定时间后,消息仍未处理,则说明已发生ANR了当程序ANR后,我们可以通过主线程Looper拿到主线程Thread,然后通过getStackTrace拿到主线程当前的调用栈,从而定位到发生ANR的地方,定位到耗时操作

定义一个线程, 用来监测主线程

class WatchDogThread : Thread() {    companion object {        val MESSAGE_WATCHDOG_TIME_TICK = 0        /** * 判定Activity发生了ANR的时间,必须要小于5秒,否则等弹出ANR,可能就被用户立即杀死了。 */        val ACTIVITY_ANR_TIMEOUT = 2000        private var lastTimeTick = -1        private var timeTick = 0    }    private val watchDogHandler = object : android.os.Handler() {        override fun handleMessage(msg: Message) {            timeTick++            timeTick %= Integer.MAX_VALUE        }    }    override fun run() {        while (true) {            watchDogHandler.sendEmptyMessage(MESSAGE_WATCHDOG_TIME_TICK)            try {                Thread.sleep(ACTIVITY_ANR_TIMEOUT.toLong())            } catch (e: InterruptedException) {                e.printStackTrace()            }            // 如果相等,说明过了ACTIVITY_ANR_TIMEOUT的时间后watchDogHandler仍没有处理消息,已经ANR了            if (timeTick == lastTimeTick) {                throw ANRException()            } else {                lastTimeTick = timeTick            }        }    }}

在Application启动监测线程

public class MyApplication extends Application {      @Override      public void onCreate() {          new WatchDogThread().start();        super.onCreate();      }  } 

当监测到发生ANR时,抛出一个自定义异常

class ANRException : RuntimeException("应用程序无响应,快来改BUG啊!!") {    init {        val mainThread = Looper.getMainLooper().thread        stackTrace = mainThread.stackTrace    }}

更多相关文章

  1. android 下载图片到本地 sdcard
  2. android之AIDL跨进程通信详解 (四)AIDL中RemoteCallbackList的使
  3. Android异步更新UI的方式之使用Handler消息传递机制
  4. Android(安卓)Thread第二次Thread.start()报错的疑问
  5. Android异步更新UI的方式之使用Handler的post(Runnabel r)方法
  6. 学习笔记:Android开源库使用方法总结
  7. Android(安卓)开发即时聊天工具 YQ :(五) 发送消息
  8. Java(Android)数据结构汇总(二)-- Set(下)
  9. android 更新UI的两种方法

随机推荐

  1. Activity与Service是否处于同一进程? Ser
  2. Android(安卓)Intent.FLAG详解
  3. android SDK安装问题
  4. android service总结
  5. Android程序分析工具Traceview的使用方法
  6. Android(安卓)Studio升级提示 Connection
  7. Android(安卓)屏幕适配(values、drawable
  8. android 访问本机ip
  9. android Path 和 PathMeasure 进阶
  10. Android(安卓)弹出菜单(类iOS UIMenuCont