当前位置:   article > 正文

Android ANR问题定位_find process anr, but unable to get anr message.

find process anr, but unable to get anr message.
  1. 什么是ANR
Appliction Not Responding 直译过来的意思就是应用程序没有响应
  • 1
  1. ANR的产生原因, 及场景
原因: 在UI线程上执行一个潜在的耗时操作

场景:
1.KeyDipatchTimeout(5 seconds)-->按键或触摸事件在特定时间内没有响应
2.BroadcastReceiver(10 seconds)-->在特定时间内无法处理完成
3.ServiceTimeout(20 seconds)-->service在特定时间内没有完成
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  1. 如何监测ANR
原理:
Android应用程序的所有交互操作和响应,都是通过主线程的消息机制来进行的。
例如当用户点击了某个Button,系统会向主线程发送消息,主线程的Looper从主线程消息队列中取出消息并处理,处理完当前消息,主线程Looper再去取出下一个消息。
当主线程做了耗时的任务,主线程的Looper就无法从消息队列中取出新的消息,所表现出的就是程序卡顿,甚至是ANR。
同理,我们在子线程往主线程发送一个消息,要是消息无法得到及时处理,那说明程序发生ANR了。

思路:
在子线程里向主线程发消息,如果过了固定时间后,消息仍未处理,则说明已发生ANR了
当程序ANR后,我们可以通过主线程Looper拿到主线程Thread,然后通过getStackTrace拿到主线程当前的调用栈,从而定位到发生ANR的地方,定位到耗时操作
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

在Application启动监测线程

public class MyApplication extends Application {  
    @Override  
    public void onCreate() {  
        new WatchDogThread().start();
        super.onCreate();  
    }  
} 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

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

class ANRException : RuntimeException("应用程序无响应,快来改BUG啊!!") {
    init {
        val mainThread = Looper.getMainLooper().thread
        stackTrace = mainThread.stackTrace
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/619482
推荐阅读
相关标签
  

闽ICP备14008679号