簡體   English   中英

在Android中加載數據庫時顯示進度對話框

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM