这是一个非常愚蠢的问题,只是因为我不喜欢我的代码向logcat输出错误,所以我询问它。
我有一个名为BackgroundCollectorProcess
的服务。它的主要任务是处理数据库中尚未报告的行。这是通过XMPP连接完成的。因此,在onStartCommand
中,我有以下内容:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.d("BGCP", "Spinning");
// Bind to our XmppConnector service to post any waiting transactions
Intent iXmpp = new Intent(getApplicationContext(), BackgroundXmppConnector.class);
bindService(iXmpp, mConnection, Context.BIND_AUTO_CREATE);
// Start the sending of all collected logs
new DeliveriesSenderTask().execute();
new GeoLogSenderTask().execute();
/*
WARNING!!
You can't call unbindService(mConnection) here - as the two main threads
for posting delivery and geolocation transactions wont have completed in
time. Thus, leaving this object unable to complete it's task.
Logcat will throw up an "error" - saying about a resource binding being
leaked in this class.
TODO: Revisit this once there is a definitive answer to the problem.
*/
// Commit suicide. BackgroundCollectorKicker will ressurect me.
stopSelf();
return Service.START_NOT_STICKY;
}
你可以看到我的大量的文本墙的评论,我遇到了一个愚蠢的logcat错误。这是:
05-16 15:30:26.243: E/ActivityThread(16078): Service com.goosesys.gaggle.services.BackgroundCollectorProcess has leaked ServiceConnection com.goosesys.gaggle.services.BackgroundCollectorProcess$1@449ddff0 that was originally bound here
05-16 15:30:26.243: E/ActivityThread(16078): android.app.ServiceConnectionLeaked: Service com.goosesys.gaggle.services.BackgroundCollectorProcess has leaked ServiceConnection com.goosesys.gaggle.services.BackgroundCollectorProcess$1@449ddff0 that was originally bound here
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.LoadedApk$ServiceDispatcher.<init>(LoadedApk.java:969)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.LoadedApk.getServiceDispatcher(LoadedApk.java:863)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ContextImpl.bindService(ContextImpl.java:1507)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ContextImpl.bindService(ContextImpl.java:1496)
05-16 15:30:26.243: E/ActivityThread(16078): at android.content.ContextWrapper.bindService(ContextWrapper.java:473)
05-16 15:30:26.243: E/ActivityThread(16078): at com.goosesys.gaggle.services.BackgroundCollectorProcess.onStartCommand(BackgroundCollectorProcess.java:70)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2681)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ActivityThread.access$1900(ActivityThread.java:146)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1337)
05-16 15:30:26.243: E/ActivityThread(16078): at android.os.Handler.dispatchMessage(Handler.java:99)
05-16 15:30:26.243: E/ActivityThread(16078): at android.os.Looper.loop(Looper.java:137)
05-16 15:30:26.243: E/ActivityThread(16078): at android.app.ActivityThread.main(ActivityThread.java:5171)
05-16 15:30:26.243: E/ActivityThread(16078): at java.lang.reflect.Method.invokeNative(Native Method)
05-16 15:30:26.243: E/ActivityThread(16078): at java.lang.reflect.Method.invoke(Method.java:511)
05-16 15:30:26.243: E/ActivityThread(16078): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
05-16 15:30:26.243: E/ActivityThread(16078): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:564)
05-16 15:30:26.243: E/ActivityThread(16078): at dalvik.system.NativeStart.main(Native Method)
这些是AsyncTasks:
private class DeliveriesSenderTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... arg0)
{
try
{
doPostDeliveries();
}
catch(Exception ex)
{
Utility.writeExceptionToLog(getApplicationContext(), ex);
}
return null;
}
}
private class GeoLogSenderTask extends AsyncTask<Void, Void, Void>
{
@Override
protected Void doInBackground(Void... params)
{
try
{
doPostGeoLogs();
}
catch(Exception ex)
{
Utility.writeExceptionToLog(getApplicationContext(), ex);
}
return null;
}
}
现在,考虑到要运行的任务本身是(或可能是)相当耗时的,它们必须在单独的线程中运行。所以,我不能调用unbindService()
,因为线程还没有完成。
unbindService
最好?显然,我已经尝试调用它一旦GeoLogSenderTask
已经完成,但我仍然得到LogCat输出这个愚蠢的消息,因为主线程将在两个asynctasks之前完成。
非常感谢任何帮助。谢谢。
将两个asyncTask实例保存为成员变量。在两个AsyncTask实现中引入onPostExecute
方法,并在两个方法中检查其他任务是否已经使用AsyncTask.getStatus == AsyncTask.Status.FINISHED
完成。当对方业务结束后,呼叫业务stopSelf()
。
protected void onPostExecute(Result result) {
if(otherTask.getStatus() == AsyncTask.Status.FINISHED) {
stopSelf();
}
};