web-dev-qa-db-ja.com

奇妙な「受信者が登録されていません」例外

OnResume()で私はします:

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

およびonPause():

unregisterReceiver(timeTickReceiver);

Android Developer Console(レポートは2つしかなく、アプリには数千人のユーザーがいます)に「Java.lang.IllegalArgumentException:Receiver notregistered」レポートが表示されます。例外はunregisterReceiver()によってトリガーされます。 。何が起こっているのでしょうか?try-catchで囲むだけでは自信がありません。

25
fhucho

特定の画面を長押しした後、すぐに2つの向きを変更すると(デバイスを上下逆にするなど)、このエラーが発生します。

nregisterReceiver のAPIドキュメントによると:

以前に登録したBroadcastReceiverの登録を解除します。

明示的には言いませんが、ご覧のとおり、まだ登録されていない場合はIllegalArgumentException: Receiver not registeredを押します。

私が使用している回避策は、Receiverをメンバーフィールドとして保存し、登録されていないときは常にnullに設定することです。つまり、nullに初期化してから、登録時にのみ設定します。これは完璧ではないかもしれませんが、それは私のクラッシュを解決します!

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;
}
21
Dan J

ブロードキャストレシーバーは、onPause()ライフサイクルメソッドで登録を解除する必要があります

protected void onPause() {
    this.unregisterReceiver(reciever);
    super.onPause();
}
6
Sunil Pandey

最も簡単なオプションは、コードの周りにtry/catchブロックをラップすることです。

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

レシーバーが実際に登録されていない状態があるかもしれません。ユーザーがアプリを終了します。

登録解除を実行する前に、レシーバーのチェックを追加してみることをお勧めします(これはいくつかのケースで実行しました)。

protected void onPause() {
  if(timeTickReceiver != null) {
    unregisterReceiver(timeTickReceiver);
  }
}
2
Eric Nordvik

BroadcastReceiveronCreate()ライフサイクルメソッドに登録する必要があります。

_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);
}    
_

また、BroadcastReceiveronDestory()ライフサイクルメソッドで登録解除する必要があります。

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

これにより、まだ登録されていないBroadcastReceiverの登録を解除するシナリオを防ぐことができます。

0
toobsco42