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

anrwatchdog.svg

ANR-WatchDog.svg

ANR-WatchDog.svg

Backing-Donate-orange.svg

ANR-WatchDog-ohos

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

项目名称:ANR-WatchDog-ohos

所属系列:鸿蒙的第三方组件适配移植

功能:可检测到鸿蒙系统的ANR错误并引发有意义的异常

项目移植状态:全部完成

调用差异:无

开发版本:sdk5,DevEco Studio2.1 beta3

项目作者和维护人:陈丛笑

目录

组件的意义

目前,ohos应用程序无法捕获和报告ANR错误。而调查ANR的唯一方法是提取文件/data/anr/traces.txt,不如选择我们自己的错误跟踪服务有效。

组件的功能

该组件设置了一个“watch dog”计时器,该计时器将检测UI线程何时停止响应。当监测到UI线程停止相应时,该组件会抛出一个具有堆栈轨迹的错误。

是否能和崩溃报告期一起使用

可以,由于这会引发错误,因此崩溃处理程序可以拦截该错误并按照所需的方式对其进行处理。

它是如何工作的

看门狗是一个简单的线程,它在循环中执行以下操作:

安排可运行对象尽快在UI线程上运行。

等待5秒钟。(默认值为5秒,但可以配置)。

查看可运行对象是否已运行。如果有,请返回1。

如果该可运行对象尚未运行,这意味着该UI线程已被阻塞至少5秒钟,则它将对所有正在运行的线程堆栈跟踪引发错误。

用法

安装

使用Devceo studio

在 app/build.gradle 中, 添加:

compile project(path: ':anr_watchdog')

在 AbilityPackage类的 onCreate中, 添加:

new ANRWatchDog().start();

阅读异常报告

该 ANRError 堆栈跟踪有点特殊, 它在你的应用程序运行的所有线程的堆栈跟踪。因此,在报告中, 每一个 caused by 部分都不是导致先例异常的原因, 而是不同线程的堆栈跟踪.

这是一个死锁示例:

鸿蒙手机的死锁示例:

2021-03-16 10:28:22.978 12535-12801/com.huawei.mytestapp E/AndroidRuntime: FATAL EXCEPTION: |ANR-WatchDog|

Process: com.huawei.mytestapp, PID: 12535

com.github.anrwatchdog.ANRError: Application Not Responding for at least 4000 ms.

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main (state = BLOCKED)

at com.huawei.mytestapp.MainAbility.lock(MainAbility.java:83)

at com.huawei.mytestapp.MainAbility.access$500(MainAbility.java:15)

at com.huawei.mytestapp.MainAbility$8.onClick(MainAbility.java:170)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AppEyeUiProbeThread (state = RUNNABLE)

at android.os.MessageQueue.nativePollOnce(Native Method)

at android.os.MessageQueue.next(MessageQueue.java:363)

at android.os.Looper.loop(Looper.java:176)

at android.os.HandlerThread.run(HandlerThread.java:67)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon (state = WAITING)

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:442)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:190)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:211)

at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:271)

从报告中,我们可以看到每一个线程的详细报告,根据Caused by 后面的堆栈追踪可以查看到死锁的原因

线程休眠报告:

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AppEyeUiProbeThread (state = RUNNABLE)

at android.os.MessageQueue.nativePollOnce(Native Method)

at android.os.MessageQueue.next(MessageQueue.java:363)

at android.os.Looper.loop(Looper.java:176)

at android.os.HandlerThread.run(HandlerThread.java:67)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon (state = WAITING)

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:442)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:190)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:211)

at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:271)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AppEyeUiProbeThread (state = RUNNABLE)

at android.os.MessageQueue.nativePollOnce(Native Method)

at android.os.MessageQueue.next(MessageQueue.java:363)

at android.os.Looper.loop(Looper.java:176)

at android.os.HandlerThread.run(HandlerThread.java:67)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon (state = WAITING)

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:442)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:190)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:211)

无限循环报告:

2021-03-16 14:48:45.471 29817-30409/com.huawei.mytestapp E/AndroidRuntime: FATAL EXCEPTION: |ANR-WatchDog|

Process: com.huawei.mytestapp, PID: 29817

com.github.anrwatchdog.ANRError: Application Not Responding for at least 4000 ms.

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: main (state = RUNNABLE)

at com.huawei.mytestapp.MainAbility.InfiniteLoop(MainAbility.java:33)

at com.huawei.mytestapp.MainAbility.access$400(MainAbility.java:15)

at com.huawei.mytestapp.MainAbility$7.onClick(MainAbility.java:164)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: AppEyeUiProbeThread (state = RUNNABLE)

at android.os.MessageQueue.nativePollOnce(Native Method)

at android.os.MessageQueue.next(MessageQueue.java:363)

at android.os.Looper.loop(Looper.java:176)

at android.os.HandlerThread.run(HandlerThread.java:67)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerDaemon (state = WAITING)

at java.lang.Object.wait(Native Method)

at java.lang.Object.wait(Object.java:442)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:190)

at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:211)

at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:271)

at java.lang.Daemons$Daemon.run(Daemons.java:137)

at java.lang.Thread.run(Thread.java:929)

Caused by: com.github.anrwatchdog.ANRError$$$_Thread: FinalizerWatchdogDaemon (state = TIMED_WAITING)

at java.lang.Thread.sleep(Native Method)

at java.lang.Thread.sleep(Thread.java:443)

at java.lang.Thread.sleep(Thread.java:359)

配置

超时

如何设置其他超时时间: ( 默认值为5000):

if (BuildConfig.DEBUG == false) {

new ANRWatchDog(10000 /*timeout*/).start();

}

调试

默认情况下,如果在进行debug或应用程序正在等待debug,watch-dog将忽略ANR。这是因为它将执行暂停和断点检测为ANR。要禁用此功能并在debug的情况下抛出ANRError,可以添加setIgnoreDebugger(true):

new ANRWatchDog().setIgnoreDebugger(true).start();

ANR回调

如果您不想在检测到ANR时不使应用程序崩溃,则可以启用回调:

new ANRWatchDog().setANRListener(new ANRWatchDog.ANRListener() {

@Override

public void onAppNotResponding(ANRError error) {

// Handle the error. For example, log it to HockeyApp:

ExceptionHandler.saveException(error, new CrashManager());

}

}).start();

在生产环境中交付应用程序时,这一点非常重要。

当由最终用户掌握时,最好不要在5秒后崩溃,而只需将ANR报告给您使用的任何报告系统即可。也许,再过几秒钟后,该应用程序将“解冻”。

Filtering reports

如果您希望仅在ANRError中报告自己的线程,而不是在所有线程(包括系统线程,例如该FinalizerDaemon线程)中报告所有线程,则可以设置前缀:仅报告名称以该前缀开头的线程。

new ANRWatchDog().setReportThreadNamePrefix("APP:").start();

然后,在启动线程时,请不要忘记将其名称设置为以该前缀开头的名称(如果要报告该名称):

public class MyAmazingThread extends Thread {

@Override

public void run() {

setName("APP: Amazing!");

/* ... do amazing things ... */

}

}

如果只想拥有主线程堆栈跟踪而没有其他所有线程,则可以:

new ANRWatchDog().setReportMainThreadOnly().start();

ANR Interceptor

有时,您想知道应用程序已经冻结了一段时间,但是还没有报告ANR错误。您可以定义在报告错误之前将被调用的拦截器。拦截器的作用是定义在给定的冻结持续时间下是否应提高或推迟ANR错误。

new ANRWatchDog(2000).setANRInterceptor(new ANRWatchDog.ANRInterceptor() {

@Override

public long intercept(long duration) {

long ret = 5000 - duration;

if (ret > 0) {

Log.w(TAG, "Intercepted ANR that is too short (" + duration + " ms), postponing for " + ret + " ms.");

}

return ret;

}

})

在此示例中,ANRWatchDog以2000毫秒的超时开始,但是拦截器将推迟错误,直到达到至少5000毫秒的冻结为止。

Watchdog thread

ANRWatchDog是一个线程,因此您可以随时中断它。

如果您正在使用Android的多进程功能进行编程(例如在新进程中启动活动),请记住,每个进程将需要ANRWatchDog线程。

Donate

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值