2012-01-08 52 views
10

當您的應用程序觸發ANR(應用程序未響應)時,是否有辦法通知?類似於默認的異常處理程序?收聽並回復ANR?

在預期「你會用它做什麼」的答案,只是日誌記錄。不「做」任何事情。

+3

@WarrenFaith Dude。你在說什麼?我接受滿意的答案。如果有人回覆,但實際上並沒有回答這個問題,我不接受他們。我的大部分問題都非常難*,或者沒有答案。通常在我問的時候,我看了很多,如果它是一個Android問題,而且我自己也找不到答案,那麼它將成爲一個非常棘手的問題。我的2K代表是回答問題。如果我的應用程序在市場上,我可以看到凍結。令人震驚的。我想親自看看。 – 2012-01-08 20:42:51

+1

@WarrenFaith PS。如果你能告訴我如何抓住ANR,我保證,你的答案將被接受。從你的「如果你的應用程序在市場上......」「,你不知道如何,所以如果你回答這個問題,我不會」接受「它,因爲它不是答案。對嗎?或者我應該接受它,只是因爲你寫了它? – 2012-01-08 20:44:19

+2

@WarrenFaith PPS ,如果你的答案是「你不能這樣做」,你需要引用一個鏈接來源,否則它只是一個猜測。 – 2012-01-08 20:45:13

回答

1

不。不像你的進程虛擬機中發生的異常可以捕獲,ANR由系統監視器在虛擬機之外生成。 Google提供info on triggers and avoidance

+0

我真的覺得沒有辦法做到這一點,這非常令人沮喪。可以(也許)用我自己的api和線程來做一些特殊的事情,但這看起來很詭異。 – 2012-02-17 00:10:21

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(); 
     } 
     } 
    }); 
... 

下面是我從logcat中得到了時,我得到了ANR日誌:

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 

所以,是的,我想這是可能的。

+0

由於您無法從其他進程或操作系統讀取日誌,因此無法使用Jelly Bean。此外,閱讀日誌不是Android SDK的一部分。 – CommonsWare 2012-08-03 13:27:02

+0

correct.since我沒有JB,我無法看到是否有任何解決方法。他們在google IO中表示,即使現在它不能工作,也可以閱讀你自己的應用程序的日誌,所以我不知道這樣的事情是否被認爲是在應用程序內部(我猜這不是)無論如何,這個解決方案從一開始就是一種解決方法。它應該適用於目前約99%的設備。 – 2012-08-03 14:00:44

+0

我有另一個想法。將在答案部分發布。 – 2012-08-04 16:21:20

5

我一直在想這個問題。你可以做到以下,雖然它相當重的手。 ANR的寫了一個線程文件到一般可讀目錄:

/data/anr/traces.txt

你可以有一個服務,在不同的進程,調查週期性文件。如果日期發生變化,並且您的應用位於頂部,那麼您可能有ANR事件。

雖然我並不是100%確定文件的格式。

+0

這是我最喜歡的答案。必須嘗試。不確定文件的格式很重要:它將包含您的應用程序包的名稱,因此您可以確保它是生成它的應用程序。想知道如果文件系統觀察員可以在該文件上工作。然後在每一個變化你可以檢查它是否包含你的包名稱。也可以在應用程序啓動時檢查,以檢查應用程序是否被用戶殺死了ANR。 – 3c71 2012-12-19 16:00:35

3

由於系統看門狗不警告應用程序,應用程序本身可以擁有自己的看門狗。 步驟很簡單,只需啓動一個線程,環路執行以下操作:

  1. 附表小碼將盡快在UI線程上運行。
  2. 等待X秒(您決定)。
  3. 查看代碼是否已經運行:如果已經運行,返回1
  4. 如果代碼沒有運行,則意味着UI線程已被阻塞至少X秒,並通過UI線程引發異常堆棧跟蹤

我寫了a small library that does exactly that,我用ACRA。

我希望它有幫助;)