我在SQLiteOpenHelper>>onCreate(SQLiteDatabase)
方法中加载数据库没有问题。
但是,当我尝试将数据库的加载包装在AsyncTask
中以显示进度条时,我一直收到数据库已关闭的消息(!)。这是什么原因?
例如,此代码可以正常工作:
@Override
public void onCreate(SQLiteDatabase db) {
...
String sqlStatement = ... //content of file with sql
for (String sqlStatement : sqlCode.split(";")) {
db.execSQL(sqlStatement);
}
}
但是如果我在类(间接)扩展AsyncTask
中包含相同的代码,我将收到错误消息,指出数据库已关闭:
@Override
public void onCreate(SQLiteDatabase db) {
new LoadDBTask(context, db, progressDialog, alertDialog).execute(new Integer[] {scriptId});
}
LoadDBTask
扩展ProgressAsyncTask
,它从AsyncTask
开始延伸。它包含与上面相同的代码。它还负责显示进度条。
此处为LoadDBTask
的代码:
public class LoadDBTask extends ProgressAsyncTask<Integer> {
protected Context context;
protected SQLiteDatabase db;
public LoadDBTask(Context context, SQLiteDatabase db, ProgressDialog progressDialog, AlertDialog alertDialog) {
super(progressDialog, alertDialog);
this.context = context;
this.db = db;
}
public boolean loadScript(String sqlCode) {
for (String sqlStatement : sqlCode.split(";")) {
sqlStatement = sqlStatement.trim();
if(!sqlStatement.isEmpty()) {
try {
db.execSQL(sqlStatement);
} catch (Exception e) {
Log.e(getClass().getSimpleName(), "Problem executing SQL statement: "+sqlStatement,e);
return false;
}
}
}
return true;
}
@Override
protected Boolean doInBackground(Integer... params) {
int scriptId = params[0];
String sqlCode;
try {
sqlCode = ResourceUtil.getFileContent(context.getResources(), scriptId);
return loadScript(sqlCode);
} catch (IOException e) {
Log.e(getClass().getSimpleName(), "Error reading script file: ",e);
return false;
}
}
}
为了完整起见,这里的代码为ProgressAsyncTask
:
public abstract class ProgressAsyncTask<Params> extends AsyncTask<Params, Integer, Boolean> {
protected ProgressDialog progressDialog;
protected AlertDialog alertDialog;
public ProgressAsyncTask(ProgressDialog progressDialog, AlertDialog alertDialog) {
this.progressDialog = progressDialog;
this.alertDialog = alertDialog;
}
@Override
protected void onProgressUpdate(Integer... changed) {
if(progressDialog != null)
progressDialog.setProgress(changed[0]);
}
@Override
protected void onPreExecute() {
if(progressDialog != null)
progressDialog.show();
}
@Override
protected void onPostExecute(Boolean result) {
if(progressDialog.isShowing())
progressDialog.dismiss();
if(!result) {
if(alertDialog != null)
alertDialog.show();
}
}
}
答案 0 :(得分:1)
您还没有向我们展示您关闭 db
的位置,所以我假设您很快就会关闭它:
new LoadDBTask(context, db, progressDialog, alertDialog).execute
(new Integer[] {scriptId});
即。在调用类中,这很可能是您的错误所在。将DB结束语句移动到onPostExecute
方法,这应解决您的问题。
当然,您必须覆盖onPostExecute
中的LoadDBTask
才能执行此操作。请注意AsyncTask
异步,因此在我提到的new LoadDBTask
声明中 阻止
答案 1 :(得分:0)
我会这样做:
private ProgressDialog progressDialog;
private Handler handler;
public yourConstructor(Context context){
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("wait");
progressDialog.setCancelable(true);
handler = new Handler();
}
@Override
public void onCreate(SQLiteDatabase db) {
progressDialog.show();
new Thread(new Runnable() {
@Override
public void run() {
//your bd access here
handler.post(new Runnable() {
@Override
public void run() {
progressDialog.cancel();
}
);
}
}).start();
}