Sta*_*tan 2 android progressdialog android-asynctask
我需要执行以下操作:当app启动时,它会运行一个活动(splashActivity),它尝试创建一个DBHelper(SQLiteDatabase)实例,该实例在创建时检查数据库是否存在,如果不存在则创建一个.
在这个数据库创建过程中,我想显示ProgressDialog并防止主线程在DB未就绪时进行处理.
splashActivity:
public class SplashActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
showSplash();
DBHelper dbHelper = new DBHelper(this);
dbHelper.close();
}
}
Run Code Online (Sandbox Code Playgroud)
DBHelper类:
public class DBHelper extends SQLiteOpenHelper {
...
private ProgressDialog mProgressDialog;
...
public DBHelper(Context context) {
super(context, DB_NAME, null, 1);
appContext=context;
dbReadable = getReadableDatabase();
if (createDB)
initDB();
}
@Override
public void onCreate(SQLiteDatabase db) {
createDB=true;
}
public void initDB() {
...
if (createDB)
restoreDB();
...
}
private void restoreDB(){
// place for db creation/restoring method call (restoreDBFromFile() etc)
// and displaying the progress
}
Run Code Online (Sandbox Code Playgroud)
我试图将AsyncTask作为DBHelper的内部类:
private class RestoreDBTask extends AsyncTask <Void, Void, String>
{
private ProgressDialog dialog;
@Override
protected void onPreExecute()
{
this.dialog = ProgressDialog.show(DBHelper.this.appContext, DBHelper.this.appContext.getResources().getString(R.string.progress_wait),
DBHelper.this.appContext.getResources().getString(R.string.progress_db_installing), true);
}
@Override
protected String doInBackground(Void... params)
{
restoreDBFromFile();
return "";
}
@Override
protected void onPostExecute(String result)
{
this.dialog.dismiss();
}
}
Run Code Online (Sandbox Code Playgroud)
所以restoreDB()是:
restoreDB() {
RestoreDBTask task = new RestoreDBTask();
task.execute();
}
Run Code Online (Sandbox Code Playgroud)
它开始显示PD的任务,但同时主线程继续,因此它崩溃导致DB没有准备好.这意味着主要线程应该暂停,而DB没有准备好所以我试图睡眠/等待/加入没有成功.好.反正它不好.
下次我从restoreDB()调用restoreDBFromFile(),以便异步任务仅用于PD显示:
restoreDB() {
RestoreDBTask task = new RestoreDBTask();
task.execute();
restoreDBFromFile();
}
Run Code Online (Sandbox Code Playgroud)
它不显示任何PD.所以我尝试在restoreDB()中创建PD:
restoreDB() {
mProgressDialog = ProgressDialog.show(appContext,
appContext.getResources().getString(R.string.progress_wait),
appContext.getResources().getString(R.string.progress_db_installing),
true);
restoreDBFromFile();
}
Run Code Online (Sandbox Code Playgroud)
但也没有PD!下次我尝试以下内容:
restoreDB() {
Thread thread = new Thread(null, new Runnable(){
@Override
public void run() {
mProgressDialog = ProgressDialog.show(appContext,
appContext.getResources().getString(R.string.progress_wait),
appContext.getResources().getString(R.string.progress_db_installing),
true);
}
}, "ProgressDialog");
thread.start();
restoreDBFromFile();
}
Run Code Online (Sandbox Code Playgroud)
再次没有PD并立即崩溃:
04-12 08:40:38.894:ERROR/AndroidRuntime(2448):ERROR:线程附加失败04-12 08:40:38.913:DEBUG/dalvikvm(2448):LinearAlloc 0x0使用639500的5242880(12%)04-12 08:40:39.094:DEBUG/ddm-heap(2454):获得功能列表请求04-12 08:40:39.492:WARN/dalvikvm(2454):threadid = 15:线程退出未捕获异常(组= 0x4001b188)04 -12 08:40:39.492:ERROR/AndroidRuntime(2454):未捕获处理程序:线程ProgressDialog由于未捕获异常退出04-12 08:40:39.504:ERROR/AndroidRuntime(2454):java.lang.RuntimeException:不能在没有调用Looper.prepare()的线程内创建处理程序04-12 08:40:39.504:ERROR/AndroidRuntime(2454):在android.os.Handler.(Handler.java:121)04-12 08:40: 39.504:ERROR/AndroidRuntime(2454):在android.app.Dialog.(Dialog.java:105)04-12 08:40:39.504:ERROR/AndroidRuntime(2454):在android.app.AlertDialog.(AlertDialog.java :63)04-12 08:40:39.504:ERROR/AndroidRuntime(2454):在android.app.ProgressDialog.(ProgressDialog.java:80)04-12 08:40 :39.504:ERROR/AndroidRuntime(2454):在android.app.ProgressDialog.(ProgressDialog.java:76)04-12 08:40:39.504:ERROR/AndroidRuntime(2454):在android.app.ProgressDialog.show(ProgressDialog) .java:101)04-12 08:40:39.504:ERROR/AndroidRuntime(2454):在android.app.ProgressDialog.show(ProgressDialog.java:90)04-12 08:40:39.504:ERROR/AndroidRuntime(2454 ):at com.taxiorder.DBHelper $ 1.run(DBHelper.java:157)04-12 08:40:39.504:ERROR/AndroidRuntime(2454):at java.lang.Thread.run(Thread.java:1096)
.
尝试了一些没有结果的事情......所以我无法弄清楚出了什么问题.
再一次 - 我只需要在restoreDB()执行时显示PD.我不能在单独的线程中运行restoreDB(),因为我需要在app继续之前完成它.我可以看到PD应该只在单独的线程中运行,但我无法管理它.
现在我还有两个问题:
1)如果PD应该在单独的线程中创建,那么它是否可以创建并显示它的线程是否完全没有做任何事情.我的意思是这样的:
new Thread(){
public void run(){
mProgressDialog = ProgressDialog.show(appContext,
appContext.getResources().getString(R.string.progress_wait),
appContext.getResources().getString(R.string.progress_db_installing),
true);
}.start();
Run Code Online (Sandbox Code Playgroud)
据我所知,线程在执行run()后立即死亡,导致无事可做,因此PD不会显示.
2)PD本身在显示时不会暂停任何线程,是吗?
尝试声明AsyncTask为活动的内部类,在那里实例化并执行它.我认为问题出在上下文中,ProgressDialog当你创建它时,你做这个的逻辑太复杂了.宣布AsyncTask活动是更常见的做法.
然后,AsyncTask必须在doInBackground方法中使用DB完成所需的一切
public class SplashActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
new RestoreDBTask().execute();
}
}
private class RestoreDBTask extends AsyncTask <Void, Void, String>
{
private ProgressDialog dialog;
@Override
protected void onPreExecute()
{
dialog = ProgressDialog.show(
SplashActivity.this,
getString(R.string.progress_wait),
getString(R.string.progress_db_installing),
true);
}
@Override
protected String doInBackground(Void... params)
{
// do all the things with DB
DBHelper dbHelper = new DBHelper(SplashActivity.this);
dbHelper.close();
return "";
}
@Override
protected void onPostExecute(String result)
{
dialog.dismiss();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5892 次 |
| 最近记录: |