java.lang.IllegalArgumentException:接收者未注册 [英] java.lang.IllegalArgumentException: Receiver not registered
问题描述
我有TrackingService组件,可基于众包跟踪我所在城市的公交车位置. TrackingService在后台运行,然后将数据传输到服务器.我有一个地图活动来显示公交车的位置,该用户是在MainActivity(作为筛选器)中选择的.
I have TrackingService component to track the location of the buses in my city based on Crowdsourcing. The TrackingService is operating in the background, then the data is transmitted to the server. I have an Map Activity to display the location of the buses, the user selected in the MainActivity( as Filter).
应用启动时,后台TrackingService在MainActivity中启动.
The background TrackingService is started in the MainActivity when the app launches.
我借助BroadcastReceiver通知有关更新的标记的map
活动,如下面的代码所示.数据正在检索到map活动中,但是我面临注销我的bReceiver
的问题.当应用在后台运行或用户按下后退"按钮时,我想注销广播,但出现以下错误:
I notifing the map
activity about the updated lcoation with the aid of the BroadcastReceiver as in the code below. The data is being retrieved to the the map activity but I am facing problem to unregister my bReceiver
. I want to unregister the broadcast when the app goes in the background or when the user presses the back button but I am getting the error below:
我该如何解决?
错误:
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);
}
推荐答案
如果在onCreate()
中注册,则必须在onDestroy()
中注销.如果要在onStop()
中注销,则必须在onStart()
中注册.
If you register in onCreate()
, you have to unregister in onDestroy()
. If you want to unregister in onStop()
you have to register in onStart()
.
在此处 http://developer中查看活动生命周期. android.com/reference/android/app/Activity.html#ActivityLifecycle
这样做的原因是onStop()
在Activity
进入后台时被调用,但不一定会被销毁.当Activity
返回到前台时,将调用onStart()
,但不会调用 onCreate()
,因此不会重新注册BroadcastReceiver
.然后,当Activity
回到后台时,onStop()
尝试再次注销,但是接收器尚未注册.
The reason for this is that onStop()
is called when the Activity
goes into the background, but is not necessarily destroyed. When the Activity
comes back to the foreground onStart()
is called, but not onCreate()
so the BroadcastReceiver
isn't re-registered. Then when the Activity
goes back into the background, onStop()
tries to unregister again, but the receiver has not been registered.
如果像这样使用接收器注册接收器,还需要使用LocalBroadcastManager
来注销接收器:
You also need to use the LocalBroadcastManager
to unregister your receiver if you used it to register it like so:
LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver);
LocalBroadcastManager
是支持库中的类:
帮助程序注册Intent广播并将其发送到流程中的本地对象.
Helper to register for and send broadcasts of Intents to local objects within your process.
这与Context
上允许系统范围广播的相同方法不同.
This is different from the same methods on Context
which allow system-wide broadcasts.
另请参见类似的问题/答案此处.
Also see a similar question/answer here.
这篇关于java.lang.IllegalArgumentException:接收者未注册的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!