其他分享
首页 > 其他分享> > android – 如何确保只有一个AsyncTask在后台运行

android – 如何确保只有一个AsyncTask在后台运行

作者:互联网

我有一个类,DownloadAndSave,从AsyncTask扩展而来.在其doInBackground方法中,它从http连接检索数据并使用OrmLite保存数据,但也清除数据库中的旧条目.所以,像这样:

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

我经常得到数据库异常:

attempt to re-open an already-closed object: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可确保以串行方式执行任务.

标签:android,sqlite,android-asynctask,ormlite
来源: https://codeday.me/bug/20190831/1775872.html