0

onCreate() に次のようなコードを持つ MapActivity があります。

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 クラスをアクティビティの内部クラスとして定義した場合に機能します。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 スレッドではありません。

アクティビティで 1 つの progressDialog を作成します。次に、Asynctasks からアクティビティの 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 に答える