Weird “Receiver not registered” exception

前端 未结 5 727
耶瑟儿~
耶瑟儿~ 2021-01-03 19:22

In onResume() I do:

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

and in onPause():

unregi         


        
相关标签:
5条回答
  • 2021-01-03 19:48

    A BroadcastReceiver should be registered in the onCreate() lifecycle method:

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

    And a BroadcastReceiver should be unregistered in the onDestory() lifecycle method:

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

    This will prevent the scenario of unregistering a BroadcastReceiver that has not yet been registered.

    0 讨论(0)
  • 2021-01-03 19:49

    A broadcast receiver should be unregister in the onPause() lifecycle method

    protected void onPause() {
        this.unregisterReceiver(reciever);
        super.onPause();
    }
    
    0 讨论(0)
  • 2021-01-03 19:55

    We've seen this error when doing a long press on a particular screen, and then immediately doing two orientation changes (e.g. turning the device upside down).

    The API docs for unregisterReceiver says:

    Unregister a previously registered BroadcastReceiver.

    It doesn't say explicitly, but as you've seen, you hit IllegalArgumentException: Receiver not registered if it isn't already registered.

    The workaround I'm using is to store my Receiver as a member field, and have it set to null whenever it is not registered, i.e. I initialize it to null, and then only set it when I register it. This might not be perfect, but it does solve my crashes!

    private Receiver mReceiver = null;
    

    From my onServiceConnected:

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

    From my onServiceDisconnected:

    if (mReceiver == null)
    {
      sLog.info("Do not unregister receiver as it was never registered");
    }
    else
    {
      sLog.debug("Unregister receiver");
      unregisterReceiver(mReceiver);
      mReceiver = null;
    }
    
    0 讨论(0)
  • 2021-01-03 19:58

    I guess there may be some states where the receiver is not actually registered before e.g. a user exits the app.

    You might want to try adding a check for the receiver before running unregister, (I've done this in several cases):

    protected void onPause() {
      if(timeTickReceiver != null) {
        unregisterReceiver(timeTickReceiver);
      }
    }
    
    0 讨论(0)
  • 2021-01-03 20:05

    Easiest option would be to wrap try/catch block around the code.

    try{
        ...
        this.unregisterReceiver(reciever);
       }
        catch(IllegalArgumentException e)
        {
            // TODO: handle exception
        }
        catch (Exception e) {
            // TODO: handle exception
        }
    
    0 讨论(0)
提交回复
热议问题