0

ユーザーが特定のボタンをタップすると、ダイアログをテーマにしたアクティビティがアプリに表示される状況があります。2 番目のアクティビティ (ダイアログ アクティビティ) の内容は を使用して取得されるため、ダイアログが読み込まれるまでHttpRequestユーザーに表示してもらいます。ProgressDialog

AsyncTask は、この目的に使用するのに最適なものと思われます。したがって、次のクラスを作成しました。

public class DetailsList extends AsyncTask<String, Integer, String> {

public static final String LOG_TAG = "DetailsList";
private Context context;
private ProgressDialog dialog;
private Activity activity;

public DetailsList(Context context) {
    this.context = context;
}

public DetailsList(Activity activity) {
    this.activity = activity;
}

@Override
protected void onPreExecute() {
    dialog = new ProgressDialog(this.context);
    dialog.setMessage("Loading...");
    dialog.setCanceledOnTouchOutside(false);
}

@Override
protected void onPostExecute(String result) {
    if(dialog.isShowing()) {
        dialog.dismiss();
    }
}

@Override
protected String doInBackground(String...params) {
    this.publishProgress(100);
    Log.d(LOG_TAG, "doInBackground started.");
    JSONObject requestContent = new JSONObject();
    JSONObject detailViewResponse = new JSONObject();
    try {
        requestContent.put("serviceId", params[0]);
        APIRequest detailViewAPI = new APIRequest(
                "http://" + GeneralConstants.SERVER_ADDRESS + "/services/",
                requestContent
                );
        detailViewResponse = detailViewAPI.request();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return detailViewResponse.toString();
}

@Override
protected void onProgressUpdate(Integer... values) {
    super.onProgressUpdate(values);
    dialog.show();
}

}

get 呼び出しが行われると、次の例外スタック トレースがあります。

12-29 05:12:29.149: W/System.err(3459): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
12-29 05:12:29.159: W/System.err(3459):     at android.os.Handler.<init>(Handler.java:121)
12-29 05:12:29.159: W/System.err(3459):     at android.app.Dialog.<init>(Dialog.java:112)
12-29 05:12:29.159: W/System.err(3459):     at android.app.AlertDialog.<init>(AlertDialog.java:114)
12-29 05:12:29.159: W/System.err(3459):     at android.app.AlertDialog.<init>(AlertDialog.java:98)
12-29 05:12:29.164: W/System.err(3459):     at android.app.ProgressDialog.<init>(ProgressDialog.java:77)
12-29 05:12:29.164: W/System.err(3459):     at threads.DetailsList.<init>(DetailsList.java:30)
12-29 05:12:29.164: W/System.err(3459):     at app.command.DetailViewDisplayCommand.execute(DetailViewDisplayCommand.java:54)
12-29 05:12:29.164: W/System.err(3459):     at commands.Command.execute(Command.java:32)
12-29 05:12:29.164: W/System.err(3459):     at gl.ObjectPicker.findObjectForValue(ObjectPicker.java:92)
12-29 05:12:29.164: W/System.err(3459):     at gl.ObjectPicker.pickObject(ObjectPicker.java:58)
12-29 05:12:29.164: W/System.err(3459):     at gl.GL1Renderer.onDrawFrame(GL1Renderer.java:111)
12-29 05:12:29.164: W/System.err(3459):     at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1520)
12-29 05:12:29.164: W/System.err(3459):     at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1244)

ダイアログを初期化した行からエラーが発生しているようです。

dialog = new ProgressDialog(this.context);
4

1 に答える 1

3
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1244)

AsyncTask は、骨の折れる操作によってメイン スレッドの速度が低下しないように設計されています。ただし、メイン スレッドではなく、OpenGL スレッドを使用しています。私はこれを自分で試したことはありませんが、次の場合はどうなりますか:

@Override
protected void onPreExecute() {
    Looper.prepare();
    Looper.loop();
    dialog = new ProgressDialog(this.context);
    dialog.setMessage("Loading...");
    dialog.setCanceledOnTouchOutside(false);
}

@Override
protected void onPostExecute(String result) {
    if(dialog.isShowing()) {
        dialog.dismiss();
    }
    Looper.quit();
}

(これはうまくいくか、間違ったスレッド例外から UI にアクセスしようとしてスローされる可能性があります。)

于 2012-12-29T00:29:18.973 に答える