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 db
so I'm going to assume you're closing it soon after:
new LoadDBTask(context, db, progressDialog, alertDialog).execute
(new Integer[] {scriptId});
Ie in your calling class and this is most likely where your error lies. Move the DB closing statement to the onPostExecute
method and that should solve your issue.
Of course, you will have to override onPostExecute
in LoadDBTask
to do this. Remember that AsyncTask
is asynchronous and as such it will not block at the new LoadDBTask
statement I mentioned.
I would do this:
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();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.