2011-02-12 54 views
19

在的onResume()我做的:古怪的 「接收器未註冊」 的例外

registerReceiver(timeTickReceiver, new IntentFilter(Intent.ACTION_TIME_TICK)); 

,並在onPause():

unregisterReceiver(timeTickReceiver); 

我看到 「java.lang.IllegalArgumentException異常:接收未註冊」 Android Developer Console中的報告(只有2個報告,我的應用有成千上萬的用戶)。異常由unregisterReceiver()觸發。會發生什麼?我不覺得有什麼信心只是用try-catch來包圍它。

+0

在哪個API版本上會發生這種情況? – 2011-02-12 14:08:12

+0

我不知道,我在錯誤報告中看不到。 – fhucho 2011-02-12 14:28:52

+0

我猜想在某些手機上``onResume`事件並不總是在`onCreate`後調用,這會導致第一個onPause這個活動出現問題。 – Xion 2011-02-15 10:44:56

回答

19

上做長按的時候,我們已經看到了這個錯誤特定的屏幕,然後立即進行兩個方向更改(例如顛倒設備)。

unregisterReceiver API文檔說:

註銷以前註冊的廣播接收器。

它沒有明確說出,但正如你所看到的,如果它尚未註冊,你就會點擊IllegalArgumentException: Receiver not registered

我正在使用的解決方法是將Receiver作爲成員字段存儲,並且只要它未被註冊,即將其初始化爲空,然後僅在註冊它時才設置它爲空。這可能不完美,但它確實解決了我的崩潰問題!

private Receiver mReceiver = null; 

從我onServiceConnected:

sLog.debug("Registering receiver"); 
mReceiver = new Receiver(); 
registerReceiver(mReceiver, filter); 

從我onServiceDisconnected:

if (mReceiver == null) 
{ 
    sLog.info("Do not unregister receiver as it was never registered"); 
} 
else 
{ 
    sLog.debug("Unregister receiver"); 
    unregisterReceiver(mReceiver); 
    mReceiver = null; 
} 
2

我想可能有一些狀態,接收器之前沒有實際註冊,例如,用戶退出應用程序。

你可能想嘗試運行註銷之前添加用於接收器的檢查,(我已經在若干情況下做到了這一點):

protected void onPause() { 
    if(timeTickReceiver != null) { 
    unregisterReceiver(timeTickReceiver); 
    } 
} 
0

一個BroadcastReceiver應在onCreate()生命週期的方法進行註冊:

private BroadcastReceiver receiver; 

@Overrride 
public void onCreate(Bundle savedInstanceState){ 
    IntentFilter filter = new IntentFilter(); 

    receiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      ... 
     } 
    } 

    registerReceiver(receiver, filter); 
}  

而一個BroadcastReceiver應在onDestory()生命週期的方法來註銷:

@Override 
protected void onDestroy() { 
    unregisterReceiver(receiver); 
} 

這將阻止註銷還未被註冊的BroadcastReceiver的場景。

5

一種廣播接收機,應在onPause()生命週期方法

protected void onPause() { 
    this.unregisterReceiver(reciever); 
    super.onPause(); 
} 
2

最簡單的辦法是註銷包裹嘗試/周圍的代碼catch塊。

try{ 
    ... 
    this.unregisterReceiver(reciever); 
    } 
    catch(IllegalArgumentException e) 
    { 
     // TODO: handle exception 
    } 
    catch (Exception e) { 
     // TODO: handle exception 
    }