[英]Showing progress dialog while loading database in Android
I am loading a database without problems in a SQLiteOpenHelper>>onCreate(SQLiteDatabase)
method. 我正在使用
SQLiteOpenHelper>>onCreate(SQLiteDatabase)
方法加载数据库而没有问题。
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(!). 但是,当我尝试将数据库的负载包装在
AsyncTask
中以显示进度条时,我不断收到消息说数据库已关闭(!)。 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 : 但是,如果我将相同的代码包装在扩展
AsyncTask
的类中(间接地),则会收到错误消息,指出数据库已关闭:
@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
. LoadDBTask
扩展了ProgressAsyncTask
,它又从AsyncTask
扩展了。 It wraps the same code than above. 它包装与上面相同的代码。 It also takes care of showing the progress bar.
它还负责显示进度栏。
Here the code for LoadDBTask
: 这里是
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
: 为了完整起见,这里是
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: 您尚未向我们显示要关闭
db
因此我假设您将在不久之后关闭它:
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. 将数据库关闭语句移至
onPostExecute
方法,这应该可以解决您的问题。
Of course, you will have to override onPostExecute
in LoadDBTask
to do this. 当然,您必须重写
onPostExecute
中的LoadDBTask
来执行此操作。 Remember that AsyncTask
is asynchronous and as such it will not block at the new LoadDBTask
statement I mentioned. 请记住,
AsyncTask
是异步的 ,因此它不会在我提到的new LoadDBTask
语句处new LoadDBTask
。
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.