gpt4 book ai didi

android - 如何在主线程中处理某些代码时显示进度对话框(在单独的线程中?)

转载 作者:搜寻专家 更新时间:2023-11-01 07:39:46 24 4
gpt4 key购买 nike


我需要执行以下操作:当应用程序启动时,它运行一个 Activity (splashActivity),该 Activity 尝试创建一个 DBHelper (SQLiteDatabase) 实例,该实例在创建时检查数据库是否存在,如果不存在则创建一个。
在此数据库创建过程中,我想显示 ProgressDialog 并在数据库未准备好时阻止主线程处理

飞溅 Activity :

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

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
}

我尝试将 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();
}
}

所以 restoreDB() 是:

restoreDB() {
RestoreDBTask task = new RestoreDBTask();
task.execute();
}

它开始显示 PD 的任务,但同时主线程继续运行,因此它崩溃,因为 DB 尚未准备好。这意味着主线程应该在数据库未准备好时暂停,所以我尝试 sleep /等待/加入但没有成功。行。反正也不好。
下次我从 restoreDB() 调用 restoreDBFromFile() 时,异步任务仅用于 PD 显示:

restoreDB() {
RestoreDBTask task = new RestoreDBTask();
task.execute();
restoreDBFromFile();
}

它不显示任何 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();
}

但也没有 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();
}

再次没有 PD 并立即崩溃:

04-12 08:40:38.894: ERROR/AndroidRuntime(2448): ERROR: thread attach failed 04-12 08:40:38.913: DEBUG/dalvikvm(2448): LinearAlloc 0x0 used 639500 of 5242880 (12%) 04-12 08:40:39.094: DEBUG/ddm-heap(2454): Got feature list request 04-12 08:40:39.492: WARN/dalvikvm(2454): threadid=15: thread exiting with uncaught exception (group=0x4001b188) 04-12 08:40:39.492: ERROR/AndroidRuntime(2454): Uncaught handler: thread ProgressDialog exiting due to uncaught exception 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.os.Handler.(Handler.java:121) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.app.Dialog.(Dialog.java:105) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.app.AlertDialog.(AlertDialog.java:63) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.app.ProgressDialog.(ProgressDialog.java:80) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.app.ProgressDialog.(ProgressDialog.java:76) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at android.app.ProgressDialog.show(ProgressDialog.java:101) 04-12 08:40:39.504: ERROR/AndroidRuntime(2454): at 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() 因为我需要它在应用程序可以继续之前完成。正如我所看到的,PD 应该只在单独的线程中运行,但我无法管理它。

现在我还有 2 个问题:

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() 后立即死亡,因为无事可做,所以 PD 不显示。
2) PD 本身不会在显示时挂起任何线程,是吗?

最佳答案

尝试将 AsyncTask 声明为 Activity 的内部类,在那里实例化并执行它。我认为问题出在 ProgressDialog 的上下文中,当你创建它时,你这样做的逻辑太复杂了。在 Activity 中声明 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();
}
}

关于android - 如何在主线程中处理某些代码时显示进度对话框(在单独的线程中?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5633425/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com