[英]Showing progress dialog while loading database in Android
我正在使用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();
}
}
}
您尚未向我們顯示要關閉 db
因此我假設您將在不久之后關閉它:
new LoadDBTask(context, db, progressDialog, alertDialog).execute
(new Integer[] {scriptId});
即在您的呼叫課程中,這很可能是您的錯誤所在。 將數據庫關閉語句移至onPostExecute
方法,這應該可以解決您的問題。
當然,您必須重寫onPostExecute
中的LoadDBTask
來執行此操作。 請記住, AsyncTask
是異步的 ,因此它不會在我提到的new LoadDBTask
語句處new LoadDBTask
。
我會這樣做:
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();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.