我有一个类,DownloadAndSaveAsyncTask扩展而来。在其doInBackground方法中,它从http连接检索数据,并使用ormlite保存数据,同时还从数据库中清除旧条目。所以,就像这样:

doInBackground()
{
  clearDb();
  dataList = fetchDataFromHttp();
  saveToDb(dataList);
}

我经常遇到数据库异常:
尝试重新打开已关闭的对象:sqlitedatabase
在cleardb()和saveToDB()函数中。
这很糟糕,因为先前调用DownloadAndSave的旧数据与DownloadAndSave的新数据混合在一起。
在我看来,我需要确保当我启动一个线程时,DownloadAndSave类的所有其他线程都已完成,或者换句话说,我一次最多需要运行一个DownloadAndSave实例。所以问题是:如何确保在任何时间点都只运行一个DownloadAndSave实例?

最佳答案

选项1。移动以上:

clearDb();
dataList = fetchDataFromHttp();
saveToDb(dataList);

在与类对象同步的单独类中:
public class WorkerClass {
    private WorkerListener workerListener;

    public static interface WorkerListener {
        public void publishWorkProgress(String data);
    }

    public WorkerClass(WorkerListener workerListener) {
        this.workerListener = workerListener;
    }

    public void performWork() {
        synchronized (WorkerClass.class) {
             clearDb();
             publish("Cleared DB");
             dataList = fetchDataFromHttp();
             publish("Got http data");
             saveToDb(dataList);
             publish("There! saved!");
        }
    }

    private void publish(String message) {
        if(workerListener != null) {
            workerListener.publishWorkProgress(message);
        }
    }

}

在您的活动中:
public class SampleActivity extends Activity {

    public void doTheThing() {
        new MyAsyncTask().execute();
    }

    private static class MyAsyncTask extends AsyncTask<Void, String, Void> implements WorkerListener {
        @Override
        protected Void doInBackground(Void... params) {
            new WorkerClass(this).performWork();
            return null;
        }

        @Override
        public void publishWorkProgress(String data) {
            publishProgress(data);
        }
    }
}

选项2:将上面的代码移到intentservice:
public class WorkerIntentService extends IntentService {
   public WorkerIntentService() {
       super(null);
   }

   @Override
    protected void onHandleIntent(Intent intent) {
       clearDb();
       dataList = fetchDataFromHttp();
       saveToDb(dataList);
    }
}

使用intentservice可以保证任务是串行执行的。

08-27 18:53