0

我有一个 MapActivity,在 onCreate() 中有与此类似的代码:

if(...) {
    ...
    new FirstAsyncTask(id, this).execute((Object[]) null);
    ...
} else {
    ...
    myLocationOverlay.runOnFirstFix(new Runnable() {
        new SecondAsyncTask(lat, lon, ActivityName.this).execute((Object[]) null);
    }
    ...
}

FirstAsyncTask 和 SecondAsyncTask 都做不同的事情,但它们都显示一个 ProgressDialog,如下所示:

public FirstAsyncTask(long id, Context context) {
    progressDialog = new ProgressDialog(context);
}

protected void onPreExecute() {
    ...
    progressDialog.show();
}

protected String doInBackground(Object... params) {
    ...
    progressDialog.dismiss();
    ...
}

这适用于 FirstAsyncTask,但无论我在对 SecondAsyncTask 的调用中进行什么更改,它总是会失败并出现以下错误:无法在未调用 Looper.prepare() 的线程内创建处理程序。我尝试将上下文参数设置为“this”、“ActivityName.this”、getApplicationContext() 和 getBaseContext()。

我对 Android 还是很陌生,所以这个“上下文”的想法让我感到困惑。我对 FirstAsyncTask 有效但 SecondAsyncTask 无效感到更加困惑。我已经看到在其他问题中提到了很多这个错误,但似乎没有一个答案有效。有任何想法吗?

编辑:在 SecondAsyncTask 的构造函数中初始化 ProgressDialog 时引发异常。

4

2 回答 2

1

在方法中编写对话关闭代码onPostExecute(),它将在 UI 线程中运行代码

@Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}

以这种方式编写您的 AsyncTask 类:

private class FirstAsyncTask extends AsyncTask<String, Void, Void> {

    ProgressDialog myDialog = null;
@Override
protected void onPreExecute() {
myDialog = ProgressDialog.show(YourActivityClass.this, "",
                "Loading Data...");
return;
}

@Override
protected Void doInBackground(String... urls) {
//Your code which you want to run in background
return null;
}

@Override
protected void onPostExecute(Void result) {
myDialog.dismiss();
return;
}
}

如果您已将 AsyncTask 类定义为 Activity 的内部类,则上述代码有效。如果您的 AsyncTask 类被定义为一个单独的类,那么您必须将活动的上下文传递给它的构造函数

ProgressDialog myDialog = null;
Context context;
public FirstAsyncTask (Context context) {
    this.context = context;     
}

@Override
protected void onPreExecute() {
myDialog = ProgressDialog.show(context, "",
            "Loading Data...");
return;
}
于 2012-08-07T03:36:46.350 回答
1

问题就在这里

myLocationOverlay.runOnFirstFix(new Runnable() {
    new SecondAsyncTask(lat, lon, ActivityName.this).execute((Object[]) null);
}

SecondAsyncTask 正在新生成的线程上构建。不是 UI 线程。

在活动中创建一个progressDialog。然后从 Asynctasks 访问 Activity 的 progressDialog。

public class MyActivity extends Activity {
    ProgressDialog mProgressDialog;

    onCreate(...){
        mProgressDialog = new ProgressDialog();
    }

    private class MyAsyncTask extends AsyncTask<...> {
        ...
        onPreExecute(...){
            mProgressDialog.show();
        }

        onPostExecute(...){
            mProgressDialog.dismiss();
        }
    }

    private class MyAsyncTask2 extends AsyncTask<...> {
        ...
        onPreExecute(...){
            mProgressDialog.show();
        }

        onPostExecute(...){
            mProgressDialog.dismiss();
        }
    }

不要尝试从 doInBackground 执行 progressDialog.dismiss(),而是将其放在 UI 线程中运行的 postExecute 中。

一旦所有这些都正常工作,您将需要设置标志,以便仅在两个任务完成后关闭进度对话框。

于 2012-08-07T03:39:20.403 回答