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