听取并回应ANR?

时间:2012-01-08 20:08:40

标签: android

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

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

5 个答案:

答案 0 :(得分:5)

我一直在考虑这个问题。你可以做以下事情,虽然它非常沉重。 ANR将线程文件写入一个通常可读的目录:

/data/anr/traces.txt

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

但我并不是100%确定文件的格式。

答案 1 :(得分:4)

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

  1. 安排小代码尽快在UI线程上运行。
  2. 等待X秒(您决定)。
  3. 查看代码是否已运行:如果已运行,请返回1
  4. 如果代码没有运行,则意味着UI线程已被阻止至少X秒,引发UI线程堆栈跟踪异常
  5. 我写了a small library that does exactly that并且我使用了ACRA。

    我希望它有所帮助;)

答案 2 :(得分:2)

没有。与您可以捕获的进程VM中发生的异常不同,ANR由VM外部的系统监视程序生成。 Google提供info on triggers and avoidance

答案 3 :(得分:0)

您可以使用侦听日志的服务(最好是前台服务)(使用线程),如果有指示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

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

答案 4 :(得分:0)

这个小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();