AlertDialog show() 导致异常

AlertDialog show() Causes Exception

当我的 ProgressDialog 为 运行 时按下后退按钮时出现此错误:

08-25 17:00:41.058  28731-28731/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@419e2088 is not valid; is your activity running?
        at android.view.ViewRootImpl.setView(ViewRootImpl.java:664)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:248)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
        at android.app.Dialog.show(Dialog.java:281)
        at thesleeplesselite.drgreenthumb.InfoBookActivity$LoadPlants.onPostExecute(InfoBookActivity.java:315)
        at thesleeplesselite.drgreenthumb.InfoBookActivity$LoadPlants.onPostExecute(InfoBookActivity.java:291)
        at android.os.AsyncTask.finish(AsyncTask.java:631)
        at android.os.AsyncTask.access0(AsyncTask.java:177)
        at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:194)
        at android.app.ActivityThread.main(ActivityThread.java:5391)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:525)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
        at de.robv.android.xposed.XposedBridge.main(XposedBridge.java:126)
        at dalvik.system.NativeStart.main(Native Method)

这些是我的代码的重要片段:

     ProgressDialog pDialog;
     android.support.v7.app.AlertDialog alert;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_infobook);
        // Load the plants via AsyncTask
        new LoadPlants().execute();
    }

    @Override
    protected void onDestroy() {
        dismissProgressDialog();
        dismissAlertDialog();
        super.onDestroy();
    }

    public class LoadPlants extends AsyncTask<Void, Void, Boolean> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            showProgressDialog("Acquiring data from the Internet. Please wait.");
        }

        @Override
        protected Boolean doInBackground(Void... arg0) {
            if (!CheckConnection.isConnectionOnline()) {
                return false;
            }
            updateJSONData();
            return true;
        }

        @Override
        protected void onPostExecute(Boolean result) {
            super.onPostExecute(result);
            if (InfoBookActivity.this.isFinishing())
                return;
            dismissProgressDialog();
            if (result == false) {
                alert = new CheckConnection().showConnectionFailureDialogBox(InfoBookActivity.this);
                alert.show();
                return;
            }
            updateList();
        }
    }

    public void showProgressDialog(String message) {
        if (pDialog == null) {
            pDialog = new ProgressDialog(InfoBookActivity.this);
            pDialog.setIndeterminate(true);
            pDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    finish();
                }
            });
            pDialog.show();
        }
        pDialog.setMessage(message);
        pDialog.show();
    }

    public void dismissProgressDialog() {
        if (pDialog != null && pDialog.isShowing()) {
            pDialog.dismiss();
        }
    }

    public void dismissAlertDialog() {
        if (alert != null && alert.isShowing()) {
            alert.dismiss();
        }
    }

这是Line 315alert.show();

基本上,会弹出一个名为pDialogProgressDialog,告诉用户它正在从网上获取数据。我希望这个 ProgressDialog 可以取消(当用户按下后退按钮时,activity 关闭并且屏幕 返回到之前的 activity)但我得到了这个例外。但我不应该这样做。我的意思是,不应该调用 alert.show(),因为我必须杀死这个 activity。顺便说一句,我正在离线测试我的应用程序。如果没有连接且用户没有取消 ProgressDialog,应用程序应显示名为 alertAlertDialog。但就我而言,它被取消了。

我试过为我的 AsyncTask 创建一个对象,而不只是调用它的默认构造函数来创建一个实例,并在我的 ProgressDialog 中为它调用 cancel(true) 方法听众,但我得到了同样的错误。

像这样声明和初始化它:LoadPlants loadPlants = new LoadPlants();

onCreate() 方法的某处:loadPlants.execute();

ProgressDialog 的取消侦听器设置为:

pDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                loadPlants.cancel(true);
                finish();
            }
        });

我遇到了泄漏之类的问题。我正在尝试修复它。如果您认为我还有其他方法可以泄漏,请告诉我在哪里以及我应该做什么。谢谢。

此外:

public AlertDialog showConnectionFailureDialogBox(final Context context) {
    AlertDialog.Builder builder = new AlertDialog.Builder(context);
    builder.setMessage(R.string.str_dialogBoxMessage);
    builder.setPositiveButton(R.string.str_dialogBoxOkButton,
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                    ((Activity) context).finish();
                }
            });
    builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
        @Override
        public void onCancel(DialogInterface dialog) {
            ((Activity) context).finish();
        }
    });
    AlertDialog alert = builder.create();
    alert.setCanceledOnTouchOutside(false);
    return alert;
}

尝试从您的代码中删除所有 finish(),看看是否能解决问题。

如果是,请查找执行顺序,可能是 Activity 在显示对话框之前完成。

创建一个 LoadPlanet 的对象,并在 activity 关闭时取消它。 OnPostExecute调用cancel后不会调用

例如 像这样开始你的任务:

LoadPlanet loadPlanetTask = new LoadPlanet();
loadPlanetTask.execute();

这样结束:

@Override
public void onPause() {
    loadPlanetTask.cancel(true);
    super.onPause();
}