奇怪的“接收者未注册”例外

时间:2011-02-12 12:56:34

标签: android broadcastreceiver

在onResume()中我做:

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

并在onPause()中:

unregisterReceiver(timeTickReceiver);

我在Android Developer Console中看到“java.lang.IllegalArgumentException:Receiver not registered”报告(只有2个报告,我的应用程序有数千个用户)。异常由unregisterReceiver()触发。可能发生什么?用try-catch围绕它我感觉不自信。

5 个答案:

答案 0 :(得分:19)

我们在特定屏幕上长按,然后立即进行两次方向更改(例如,将设备翻转过来)时看到此错误。

unregisterReceiver的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;
}

答案 1 :(得分:6)

广播接收器应该在onPause()生命周期方法

中取消注册
protected void onPause() {
    this.unregisterReceiver(reciever);
    super.onPause();
}

答案 2 :(得分:2)

我猜可能会有一些状态,接收者实际上没有注册,例如用户退出应用程序。

你可能想在运行取消注册之前尝试为接收器添加一个检查,(我在几种情况下已经这样做了):

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

答案 3 :(得分:2)

最简单的选择是在代码周围包装try / catch块。

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

答案 4 :(得分: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的情况。