I am loading a database without problems in a SQLiteOpenHelper>>onCreate(SQLiteDatabase) method.
However, when I try to wrap the loading of the database in an AsyncTask in order to show a progress bar, I keep receiving the message that the database is closed(!). What is the reason of that ?
As an example, this code works fine :
@Override
public void onCreate(SQLiteDatabase db) {
...
String sqlStatement = ... //content of file with sql
for (String sqlStatement : sqlCode.split(";")) {
db.execSQL(sqlStatement);
}
}
But if I wrap the same code in a class (indirectly) extending AsyncTask, I will receive the error message saying that the database is closed :
@Override
public void onCreate(SQLiteDatabase db) {
new LoadDBTask(context, db, progressDialog, alertDialog).execute(new Integer[] {scriptId});
}
LoadDBTask extends ProgressAsyncTask, that at it turns extends from AsyncTask. It wraps the same code than above. It also takes care of showing the progress bar.
Here the code for 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;
}
}
}
And for completeness, here the code of 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();
}
}
}
You haven’t shown us where you’re closing the
dbso I’m going to assume you’re closing it soon after:I.e. in your calling class and this is most likely where your error lies. Move the DB closing statement to the
onPostExecutemethod and that should solve your issue.Of course, you will have to override
onPostExecuteinLoadDBTaskto do this. Remember thatAsyncTaskis asynchronous and as such it will not block at thenew LoadDBTaskstatement I mentioned.