好的,所以我构建了一个使用远程服务进行实时GPS跟踪的应用程序。我使用以下代码启动并绑定到服务。
远程服务使用aidl,设置通知图标,运行GPS和locationListener。在onLocationChanged中,处理程序通过回调将数据发送回调用者。非常直接来自在线示例和资源。
即使应用关闭,我也想让服务继续运行。当应用程序重新启动时,我希望应用程序再次绑定到服务(如果正在运行则使用现有服务)并再次从跟踪器接收数据。
我目前将应用模式设置为singleTask,并且由于其他问题而无法使用单一实例。
我的问题是即使在应用程序和服务从应用程序本身或从AdvancedTaskKiller或Forceclose关闭后经常退出,该服务将重新启动并初始化GPS。触摸通知将打开该应用程序。我再次停止跟踪,删除通知并关闭GPS关闭应用程序,几秒钟后服务重新启动。阻止它的唯一方法是关闭手机。
我该怎么做才能阻止这种情况发生。是否与操作方式有关? START_NOT_STICKY或START_REDELIVER_INTENT?或者我需要使用stopSelf()?
我的理解是,如果我使用bindService()时服务没有运行,那么服务将被创建......所以我真的需要使用start / stopService吗?如果我希望服务在应用程序关闭后运行,我想我需要使用它。这就是我没有在onDestroy()中取消绑定/停止服务的原因。这是对的吗?
我没有看到任何其他信息,所以我,我不确定在哪里看。
请帮忙!谢谢 帕特里克
//Remote Service Startup
try{
startService();
}catch (Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show(); }
}
try{
bindService();
}catch (Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
//Remote service shutdown
try {
unbindService();
}catch(Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
try{
stopService();
}catch(Exception e) {
Toast.makeText(ctx, e.getMessage().toString(), Toast.LENGTH_SHORT).show();
}
private void startService() {
if( myAdapter.trackServiceStarted() ) {
if(SETTING_DEBUG_MODE)
Toast.makeText(this, "Service already started", Toast.LENGTH_SHORT).show();
started = true;
if(!myAdapter.trackDataExists())
insertTrackData();
updateServiceStatus();
} else {
startService( new Intent ( "com.codebase.TRACKING_SERVICE" ) );
Log.d( "startService()", "startService()" );
started = true;
updateServiceStatus();
}
}
private void stopService() {
stopService( new Intent ( "com.codebase.TRACKING_SERVICE" ) );
Log.d( "stopService()", "stopService()" );
started = false;
updateServiceStatus();
}
private void bindService() {
bindService(new Intent(ITrackingService.class.getName()),
mConnection, Context.BIND_AUTO_CREATE);
bindService(new Intent(ITrackingSecondary.class.getName()),
mTrackingSecondaryConnection, Context.BIND_AUTO_CREATE);
started = true;
}
private void unbindService() {
try {
mTrackingService.unregisterCallback(mCallback);
} catch (RemoteException e) {
// There is nothing special we need to do if the service
// has crashed.
e.getMessage();
}
try {
unbindService(mTrackingSecondaryConnection);
unbindService(mConnection);
} catch (Exception e) {
// There is nothing special we need to do if the service
// has crashed.
e.getMessage();
}
started = false;
}
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mTrackingService = ITrackingService.Stub.asInterface(service);
// We want to monitor the service for as long as we are
// connected to it.
try {
mTrackingService.registerCallback(mCallback);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mTrackingService = null;
}
};
private ServiceConnection mTrackingSecondaryConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// Connecting to a secondary interface is the same as any
// other interface.
mTrackingSecondaryService = ITrackingSecondary.Stub.asInterface(service);
try{
mTrackingSecondaryService.setTimePrecision(SETTING_TIME_PRECISION);
mTrackingSecondaryService.setDistancePrecision(SETTING_DISTANCE_PRECISION);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
}
public void onServiceDisconnected(ComponentName className) {
mTrackingSecondaryService = null;
}
};
//TrackService onDestry()
public void onDestroy() {
try{
if(lm != null) {
lm.removeUpdates(this);
}
if(mNotificationManager != null) {
mNotificationManager.cancel(R.string.local_service_started);
}
Toast.makeText(this, "Service stopped", Toast.LENGTH_SHORT).show();
}catch (Exception e){
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}
// Unregister all callbacks.
mCallbacks.kill();
// Remove the next pending message to increment the counter, stopping
// the increment loop.
mHandler.removeMessages(REPORT_MSG);
super.onDestroy();
}
ServiceConnectionLeaked:我看到了很多这些:
04-21 09:25:23.347: ERROR/ActivityThread(3246): Activity com.codebase.GPSTest has leaked ServiceConnection com.codebase.GPSTest$6@4482d428 that was originally bound here
04-21 09:25:23.347: ERROR/ActivityThread(3246): android.app.ServiceConnectionLeaked: Activity com.codebase.GPSTest has leaked ServiceConnection com.codebase.GPSTest$6@4482d428 that was originally bound here
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread$PackageInfo$ServiceDispatcher.<init>(ActivityThread.java:977)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread$PackageInfo.getServiceDispatcher(ActivityThread.java:872)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ApplicationContext.bindService(ApplicationContext.java:796)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.content.ContextWrapper.bindService(ContextWrapper.java:337)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at com.codebase.GPSTest.bindService(GPSTest.java:2206)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at com.codebase.GPSTest.onStartStopClick(GPSTest.java:1589)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at com.codebase.GPSTest.onResume(GPSTest.java:1210)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1149)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.Activity.performResume(Activity.java:3763)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2937)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2965)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2516)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3625)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.access$2300(ActivityThread.java:119)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1867)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.os.Handler.dispatchMessage(Handler.java:99)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.os.Looper.loop(Looper.java:123)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at android.app.ActivityThread.main(ActivityThread.java:4363)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at java.lang.reflect.Method.invokeNative(Native Method)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at java.lang.reflect.Method.invoke(Method.java:521)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
04-21 09:25:23.347: ERROR/ActivityThread(3246): at dalvik.system.NativeStart.main(Native Method)
并且这些:这是好的,还是我需要确保我停用/关闭
04-21 09:58:55.487: INFO/dalvikvm(3440): Uncaught exception thrown by finalizer (will be discarded):
04-21 09:58:55.487: INFO/dalvikvm(3440): Ljava/lang/IllegalStateException;: Finalizing cursor android.database.sqlite.SQLiteCursor@447ef258 on gps_data that has not been deactivated or closed
04-21 09:58:55.487: INFO/dalvikvm(3440): at android.database.sqlite.SQLiteCursor.finalize(SQLiteCursor.java:596)
04-21 09:58:55.487: INFO/dalvikvm(3440): at dalvik.system.NativeStart.run(Native Method)