接收器未注册exception错误?

在我的开发人员控制台中,人们不断报告我无法在任何手机上重现的错误。 有一个人留言说当他们试图打开我的电池服务的设置屏幕时,他得到了这个消息。 正如您从错误中可以看到的那样,接收方没有注册。

java.lang.RuntimeException: Unable to stop service .BatteryService@4616d688: java.lang.IllegalArgumentException: Receiver not registered: com.app.notifyme.BatteryService$BatteryNotifyReceiver@4616d9d0 at android.app.ActivityThread.handleStopService(ActivityThread.java:3164) at android.app.ActivityThread.access$3900(ActivityThread.java:129) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2173) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:143) at android.app.ActivityThread.main(ActivityThread.java:4701) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:521) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.IllegalArgumentException: Receiver not registered:com..BatteryService$BatteryNotifyReceiver@4616d9d0 at android.app.ActivityThread$PackageInfo.forgetReceiverDispatcher(ActivityThread.java:805) at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:859) at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:331) at com.app.notifyme.BatteryService.onDestroy(BatteryService.java:128) at android.app.ActivityThread.handleStopService(ActivityThread.java:3150) 

我注册在我的onCreate

 @Override public void onCreate(){ super.onCreate(); SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this); IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); registerReceiver(batteryNotifyReceiver,filter); pref.registerOnSharedPreferenceChangeListener(this); } 

在onDestroy中取消注册,并使用偏好侦听器

  @Override public void onDestroy(){ super.onDestroy(); unregisterReceiver(batteryNotifyReceiver); } 

这是我的接收器在服务

 private final class BatteryNotifyReceiver extends BroadcastReceiver { boolean connected; @Override public void onReceive(Context context, Intent intent) { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); SharedPreferences.Editor edit = prefs.edit(); updatePreferences(prefs); level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1); if(intent.getAction().equals(Intent.ACTION_POWER_CONNECTED)){ connected = true; }else if(intent.getAction().equals(Intent.ACTION_POWER_DISCONNECTED)){ connected = false; }else if(intent.getAction().equals(Intent.ACTION_BATTERY_CHANGED)){ if(level < lastLevel){ if(level > 40){ edit.putBoolean("first", false).commit(); edit.putBoolean("second", false).commit(); edit.putBoolean("third", false).commit(); edit.putBoolean("fourth",false).commit(); edit.putBoolean("fifth", false).commit(); } if(level == 40){ if(!first){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("first", true).commit(); } }else if(level == 30){ if(!second){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("second", true).commit(); } }else if(level == 20){ if(!third){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("third", true).commit(); } }else if(level == 15){ if(!fourth){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("fourth", true).commit(); } }else if(level == 5){ if(!fifth){ notification(context,battColor,battBlink,battVib,battSound); edit.putBoolean("fifth", true).commit(); } } lastLevel = temp; } } Intent i = new Intent(context,BatteryNotifyReceiver.class); context.startService(i); } } 

任何想法为什么他们会得到这个错误?

你问题的根源在这里:

  unregisterReceiver(batteryNotifyReceiver); 

如果接收者已经被注销(可能在你没有包含在这个post中的代码中),或者没有注册,那么调用unregisterReceiver会抛出IllegalArgumentExceptionexception。 在你的情况下,你只需要为这个exception设置特殊的try / catch,并忽略它(假设你不能或不想控制在同一个接收者上调用unregisterReceiver的次数)。

在任何地方使用这个代码unregisterReceiver:

 if (batteryNotifyReceiver!=null) { unregisterReceiver(batteryNotifyReceiver); batteryNotifyReceiver=null; } 

正如其他答案中所提到的,抛出exception是因为每个对registerReceiver调用都没有被一个unregisterReceiver调用所匹配。 为什么不?

对于每个onCreate调用, Activity并不总是具有匹配的onDestroy调用。 如果系统内存不足,您的应用程序将被驱逐,而无需调用onDestroy

放置registerReceiver调用的正确位置是onResume调用,而onPause unregisterReceiver 。 这对电话总是匹配。 请参阅活动生命周期图以获取更多详细信息。 http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

您的代码将更改为:

 SharedPreferences mPref IntentFilter mFilter; @Override public void onCreate(){ super.onCreate(); mPref = PreferenceManager.getDefaultSharedPreferences(this); mFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_POWER_CONNECTED); filter.addAction(Intent.ACTION_POWER_DISCONNECTED); } @Override public void onResume() { registerReceiver(batteryNotifyReceiver,mFilter); mPref.registerOnSharedPreferenceChangeListener(this); } @Override public void onPause(){ unregisterReceiver(batteryNotifyReceiver, mFilter); mPref.unregisterOnSharedPreferenceChangeListener(this); } 

编辑:这是inazaruk和electrichead的答案…我遇到了类似的问题,他们发现了以下…

这个问题有一个长期存在的错误: http : //code.google.com/p/android/issues/detail?id=6191

看起来它是围绕Android 2.1开始的,并且从那以后就已经出现在所有的Android 2.x版本中。 我不确定它是否仍然是Android 3.x或4.x中的问题。

无论如何,这个StackOverflow文章解释了如何正确解决这个问题(它看起来并不相关的URL,但我保证是这样)

为什么键盘滑动崩溃我的应用程序?

注册时要小心

 LocalBroadcastManager.getInstance(this).registerReceiver() 

你不能取消注册

  unregisterReceiver() 

你必须使用

 LocalBroadcastManager.getInstance(this).unregisterReceiver() 

或应用程序将崩溃,日志如下:

09-30 14:00:55.458 19064-19064 / com.jialan.guangdian.view E / AndroidRuntime:致命exception:主进程:com.jialan.guangdian.view,PID:19064 java.lang.RuntimeException:无法停止服务com.google.android.exoplayer.demo.player.PlayService@141ba331:java.lang.IllegalArgumentException:Receiver not registered:com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584 at android.app.ActivityThread。在android.app.ActivityThread.access $ 2200(ActivityThread.java:148)android.app.ActivityThread $ h.handleMessage(ActivityThread.java:1395)android.os.Handler.dispatchMessage()上的handleStopService(ActivityThread.java:2941) Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5310)at java.lang.reflect.Method.invoke(Native Method)在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:901)at com.android.internal.os.ZygoteInit.main(java.lang.reflect.Method.invoke(Method.java:372))。 (ZygoteInit.java:696)导致:java.lang.IllegalArgumentException:接收器未注册:com.google.android.exoplayer.demo.player.PlayService$PlayStatusReceiver@19538584在android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java: 769)at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:1794)at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:510)at com.google.android.exoplayer.demo.player.PlayService.onDestroy(PlayService .java:542)at android.app.ActivityThread.handleStopService(ActivityThread.java:2924)at android.app.ActivityThread.access $ 2200(ActivityThread.java:148)at android.app.ActivityThread $ H.handleMessage(ActivityThread.java :1395)at android.os.Handler.dispatchMessage(Handler.java:102)at android.os.Looper.loop(Looper.java:135)at android.app.ActivityThread.main(ActivityThread.java:5310)at java .lang.reflect.Method.invoke(Native Method)at java.lang.reflect.Method.invoke(Method.java:372)at com.android.internal.os.ZygoteInit $ MethodA ndArgsCaller.run(ZygoteInit.java:901)at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:696)

我用了一个try – catch块来暂时解决这个问题。

 // Unregister Observer - Stop monitoring the underlying data source. if (mDataSetChangeObserver != null) { // Sometimes the Fragment onDestroy() unregisters the observer before calling below code // See <a>http://stackoverflow.com/questions/6165070/receiver-not-registered-exception-error</a> try { getContext().unregisterReceiver(mDataSetChangeObserver); mDataSetChangeObserver = null; } catch (IllegalArgumentException e) { // Check wether we are in debug mode if (BuildConfig.IS_DEBUG_MODE) { e.printStackTrace(); } } } 

将接收者声明为null,然后分别在活动的onResume()和onPause()中注册和取消注册方法。

 @Override protected void onResume() { super.onResume(); if (receiver == null) { filter = new IntentFilter(ResponseReceiver.ACTION_RESP); filter.addCategory(Intent.CATEGORY_DEFAULT); receiver = new ResponseReceiver(); registerReceiver(receiver, filter); } } @Override protected void onPause() { super.onPause(); if (receiver != null) { unregisterReceiver(receiver); receiver = null; } } 

当注册BR的UI组件被破坏时,BR也被破坏。 因此,当代码取消注册时,BR可能已经被销毁。

对于任何人会遇到这个问题,他们尝试了所有build议,并没有任何工作,这是我如何sorting我的问题,而不是做LocalBroadcastManager.getInstance(this).registerReceiver(...)我第一次创build一个局部variablestypes的LocalBroadcastManager,

 private LocalBroadcastManager lbman; 

并使用该variables在广播接收器上执行注册和注销,即

 lbman.registerReceiver(bReceiver); 

 lbman.unregisterReceiver(bReceiver);