java.lang.IllegalArgumentException:Receiver未注册

我有TrackingService组件,根据Crowdsourcing跟踪我所在城市的公交车位置。 TrackingService在后台运行,然后将数据传输到服务器。 我有一个Map Activity来显示总线的位置,在MainActivity中选择的用户(作为Filter)。

应用程序启动时,后台TrackingService在MainActivity中启动。

我在BroadcastReceiver的帮助下通知了有关更新的lcoation的map活动,如下面的代码所示。 正在检索数据到地图活动,但我要bReceiver注册我的bReceiver问题。 我想在应用程序进入后台或用户按下后退按钮时取消注册广播,但我收到以下错误:

我该如何解决?

错误:

 08-27 22:43:04.594: E/AndroidRuntime(19588): FATAL EXCEPTION: main 08-27 22:43:04.594: E/AndroidRuntime(19588): Process: com.bustracker, PID: 19588 08-27 22:43:04.594: E/AndroidRuntime(19588): java.lang.RuntimeException: Unable to stop activity {com.bustracker/com.bustracker.Map}: java.lang.IllegalArgumentException: Receiver not registered: com.bustracker.Map$1@2483d256 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4156) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:4219) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.access$1500(ActivityThread.java:177) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1502) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.os.Handler.dispatchMessage(Handler.java:102) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.os.Looper.loop(Looper.java:145) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.main(ActivityThread.java:5944) 08-27 22:43:04.594: E/AndroidRuntime(19588): at java.lang.reflect.Method.invoke(Native Method) 08-27 22:43:04.594: E/AndroidRuntime(19588): at java.lang.reflect.Method.invoke(Method.java:372) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1389) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1184) 08-27 22:43:04.594: E/AndroidRuntime(19588): Caused by: java.lang.IllegalArgumentException: Receiver not registered: com.bustracker.Map$1@2483d256 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.LoadedApk.forgetReceiverDispatcher(LoadedApk.java:822) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ContextImpl.unregisterReceiver(ContextImpl.java:2038) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.content.ContextWrapper.unregisterReceiver(ContextWrapper.java:528) 08-27 22:43:04.594: E/AndroidRuntime(19588): at com.bustracker.Map.onStop(Map.java:418) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.Instrumentation.callActivityOnStop(Instrumentation.java:1275) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.Activity.performStop(Activity.java:6493) 08-27 22:43:04.594: E/AndroidRuntime(19588): at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:4151) 08-27 22:43:04.594: E/AndroidRuntime(19588): ... 10 more 

TrackingService类:

 public class TrackingService extends Service implements LocationListener { public double pLong; public double pLat; ... @Override public int onStartCommand(Intent intent, int flags, int startId) { detectLocation(); return START_STICKY; } private void detectLocation() { lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE); lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30 * 1000, 0, this); } @Override public void onLocationChanged(Location location) { if (location != null) { pLong = location.getLongitude(); pLat = location.getLatitude(); Intent intent = new Intent(Map.RECEIVE_latLng); intent.putExtra("location",location); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); ..... } } 

地图活动:

  public class Map extends FragmentActivity implements OnMapReadyCallback { public static final String RECEIVE_latLng = "com.bustracker.RECEIVE_latLng"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.map); LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(this); IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(RECEIVE_latLng); bManager.registerReceiver(bReceiver, intentFilter); } private BroadcastReceiver bReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if(intent.getAction().equals(RECEIVE_latLng)) { Location location = intent.getParcelableExtra("location"); double lng = location.getLongitude(); double lat = location.getLatitude(); LatLng ll = new LatLng(lat, lng); MarkerOptions markerOpt = new MarkerOptions().title("My Location") .position(ll); System.out.println("ABC map: "+ lat + " ; " + lng); myLocatMarker = map.addMarker(markerOpt); } } }; } @Override protected void onStop() { super.onStop(); unregisterReceiver(bReceiver); } 

Related of "java.lang.IllegalArgumentException:Receiver未注册"

如果在onCreate()注册,则必须在onDestroy()注销。 如果要在onStop()取消注册,则必须在onStart()注册。

在这里查看活动生命周期http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle

原因是当Activity进入后台时调用onStop() ,但不一定要销毁。 当Activity返回前台时onStart()被调用,而不是 onCreate()因此不会重新注册BroadcastReceiver 。 然后,当Activity返回后台时, onStop()会再次尝试取消注册,但接收方尚未注册。

您还需要使用LocalBroadcastManager取消注册您的接收器,如果您使用它来注册它,如下所示:

 LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver); 

LocalBroadcastManager是支持库中的一个类:

帮助程序注册并向您的进程中的本地对象发送Intent广播。

这与允许系统范围广播的Context上的相同方法不同。

另请参阅此处的类似问题/答案。

(当然,如果你愿意的话)你可以在onStop()onResume()注册或取消注册它们,只需用try-catch包装它:

try{ getActivity().registerReceiver(receiver,filter); } catch (Exception e){ // already registered } try{ getActivity().registerReceiver(receiver,filter); } catch (Exception e){ // already registered }或者

try{ getActivity().unregisterReceiver(receiver); } catch (Exception e){ // already unregistered }

请记住,您必须在相同的上下文中注册和取消注册。 例如,不要注册应用程序上下文并取消注册w /活动上下文。

不要这样做

 getApplicationContext().registerReceiver(myReceiver, myIntentFilter); unregisterReceiver(myReceiver); 

这样做(在活动内)

 registerReceiver(myReceiver, myIntentFilter); unregisterReceiver(myReceiver); 

我通常在onPostResume()onResume()注册,并在super.onPause()调用之后onPause()取消注册。

例子:

 protected void onPostResume() { super.onPostResume(); registerReceiver(myReceiver, myIntentFilter); } 

 protected void onPause() { unregisterReceiver(tripInCartReceiver1); //called after unregistering super.onPause(); }