我有一个类,DownloadAndSave
从AsyncTask
扩展而来。在其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可以保证任务是串行执行的。