2012-01-21 156 views
1

我在SQLiteOpenHelper>>onCreate(SQLiteDatabase)方法中加載沒有問題的數據庫。在Android中加載數據庫時顯示進度對話框

但是,當我嘗試在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(); 
    } 
} 
} 

回答

1

你沒有向我們顯示你在哪裏正在關閉db所以我會假設你不久後關閉它:

new LoadDBTask(context, db, progressDialog, alertDialog).execute 
    (new Integer[] {scriptId}); 

即在你的呼叫班,這很可能是你的錯誤所在。將DB閉幕聲明移至onPostExecute方法,這應該可以解決您的問題。

當然,您必須重寫onPostExecuteLoadDBTask才能這樣做。請記住AsyncTask異步,因此它將而不是塊在我提到的new LoadDBTask聲明。

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(); 
} 
+0

OP的問題應用了一個** AsyncTask ** .. –

相關問題