AsynTask and Service binding



这是一个非常愚蠢的问题,只是因为我不喜欢我的代码向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();
    }
  };

相关内容

  • 没有找到相关文章

最新更新