聆听并回应 ANR?

Posted

技术标签:

【中文标题】聆听并回应 ANR?【英文标题】:Listen and respond to ANR? 【发布时间】:2012-02-05 12:57:26 【问题描述】:

有没有办法在您的应用触发 ANR(应用程序无响应)时获得通知?类似于默认异常处理程序?

期待“你会用它做什么”的答案,只是记录。不“做”任何事情。

【问题讨论】:

@WarrenFaith 伙计。你在说什么?我接受满意的答复。如果有人回复,但实际上并没有回答问题,我不接受他们。我的大部分问题真的很难,或者没有答案。通常到我问的时候,我已经看了很多,如果这是一个 android 问题,而我自己找不到答案,那将是一个非常棘手的问题。我的 2K 代表来自回答问题。如果我的应用程序在市场上,我可以看到冻结。令人震惊。我想自己抓住它们。 @WarrenFaith PS。如果你能告诉我如何捕捉 ANR,我保证,你的回答将被接受。从您的“如果您的应用程序在市场上......”来看,您不知道如何,所以如果您这样回答,我不会“接受”它,因为它不是答案。正确的?还是因为你写的我就应该接受? @WarrenFaith PPS,如果您的回答是“您不能那样做”,您需要引用带有链接的来源。否则只是猜测。 @WarrenFaith "Dude" 并不意味着所有权。所以,既然我不太了解你们的社区规则,我该怎么处理那些答案很糟糕的问题呢?我刚刚浏览了我的公开文件,发现有 2 个处于临界状态,所以接受了它们,即使他们有点打电话进来。其余的都有提交,但并没有真正“回答”任何事情。我不能完全“拒绝”他们。 @WarrenFaith 被冒犯了?不知道那是冒犯。那是我表达我的愤怒。就像,“伙计,让我休息一下”。我同意当我弄清楚时我应该填写自己的答案。当人们填写快速答案时,我通常不回复,因为他们显然只是想提高他们的分数。如果有合理的回答尝试,我想我一直在交流,至少最近是这样。新人的时候不懂规矩。无论如何,低于 50% 的可疑程度如何?我的大部分问题都没有很好的答案。期间。 【参考方案1】:

由于系统看门狗不会警告应用程序,因此应用程序本身可以拥有自己的看门狗。 步骤很简单,只需启动一个循环执行以下操作的线程:

    尽快安排小代码在 UI 线程上运行。 等待 X 秒(由您决定)。 查看代码是否已运行:如果已运行,则返回 1 如果代码未运行,则表示 UI 线程已被阻塞至少 X 秒,引发 UI 线程堆栈跟踪异常

我已经写了a small library that does exactly that 并且我在 ACRA 中使用。

希望对你有帮助;)

【讨论】:

我刚刚将这个库集成到我的应用程序中,它运行良好!非常感谢。【参考方案2】:

没有。与您可以捕获的进程 VM 内发生的异常不同,ANR 是由 VM 外部的系统看门狗生成的。谷歌提供info on triggers and avoidance

【讨论】:

我真的认为没有办法做到这一点,这非常令人沮丧。可以(也许)用我自己的 api 和线程做一些特别的事情来捕捉,但这似乎很 hacky。【参考方案3】:

我一直在思考这个问题。您可以执行以下操作,尽管它相当笨拙。 ANR 将一个线程文件写入一个一般可读的目录:

/data/anr/traces.txt

您可以让服务在不同的进程中定期轮询该文件。如果日期发生变化,并且您的应用位于顶部,那么您可能遇到了 ANR 事件。

不过,我不能 100% 确定文件的格式。

【讨论】:

这是我最喜欢的答案。得试试那个。不确定文件的格式是否重要:它将包含您的应用程序包的名称,因此您可以确保生成它的是您的应用程序。想知道文件系统观察者是否会处理该文件。然后在每次更改时,您都可以检查它是否包含您的包名称。也可以在应用启动时检查,以检查应用是否在 ANR 之后被用户杀死。【参考方案4】:

这个小的ANR-WatchDog 线程可以帮助您监控应用程序的线程并在发生 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 的日志,请处理它。

这里有一个导致 ANR 的应用的小示例:

...
findViewById(R.id.button).setOnClickListener(new OnClickListener()
  
    @Override
    public void onClick(final View v)
      
      try
        
        Thread.sleep(10000);
        
      catch(final InterruptedException e)
        
        // TODO Auto-generated catch block
        e.printStackTrace();
        
      
  );
...

这是我在获得 ANR 时从 logcat 获得的日志:

08-03 13:02:37.746: E/ActivityManager(158): ANR in com.example.anr (com.example.anr/.MainActivity)
08-03 13:02:37.746: E/ActivityManager(158): Reason: keyDispatchingTimedOut
08-03 13:02:37.746: E/ActivityManager(158): Load: 6.19 / 2.37 / 0.86
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 5598ms to 0ms ago:
08-03 13:02:37.746: E/ActivityManager(158):   2.6% 158/system_server: 2.5% user + 0.1% kernel / faults: 86 minor
08-03 13:02:37.746: E/ActivityManager(158):   0.5% 298/com.android.phone: 0.3% user + 0.1% kernel / faults: 15 minor
08-03 13:02:37.746: E/ActivityManager(158):   0% 35/rild: 0% user + 0% kernel
08-03 13:02:37.746: E/ActivityManager(158): 4.6% TOTAL: 3.9% user + 0.6% kernel
08-03 13:02:37.746: E/ActivityManager(158): CPU usage from 2029ms to 2654ms later:
08-03 13:02:37.746: E/ActivityManager(158):   11% 158/system_server: 4.8% user + 6.4% kernel / faults: 2 minor
08-03 13:02:37.746: E/ActivityManager(158):     11% 192/InputDispatcher: 4.8% user + 6.4% kernel
08-03 13:02:37.746: E/ActivityManager(158):     1.6% 163/Compiler: 1.6% user + 0% kernel
08-03 13:02:37.746: E/ActivityManager(158):     1.6% 193/InputReader: 0% user + 1.6% kernel
08-03 13:02:37.746: E/ActivityManager(158): 18% TOTAL: 9.3% user + 9.3% kernel

所以,是的,我认为这是可能的。

【讨论】:

对于 Jelly Bean 来说这是不可能的,因为您无法从其他进程或操作系统读取日志。此外,读取日志不是 Android SDK 的一部分。 correct.since 我没有 JB ,我看不出是否有任何解决方法。他们在 google IO 中说,即使现在它不起作用,也可以阅读您自己的应用程序的日志,所以我不知道这样的事情是否被认为是在应用程序内部(我想不是) .无论如何,这个解决方案从一开始就是一种解决方法。它应该适用于目前大约 99% 的设备。 我有另一个想法。将在答案部分发布。

以上是关于聆听并回应 ANR?的主要内容,如果未能解决你的问题,请参考以下文章

Laravel/000webhost/邮递员。无法得到任何回应

没有得到 Alamofire 的回应

新手求助,Arduino联网后,如何回应HttpClient的GET请求

邮递员“无法得到任何回应,连接到时出错。”

字节回应阿里涉侵犯男员工曾面试并通过一面;HarmonyOS 2.0用户数升至5000万|极客头条...

字节回应阿里涉侵犯男员工曾面试并通过一面;HarmonyOS 2.0用户数升至5000万|极客头条...