web-dev-qa-db-ja.com

alertDialog show()メソッドでアクティビティがウィンドウをリークしました

AlertDialogを使用しているため、実行時にウィンドウリークエラーが発生します。

以下のコードでエラー行を指摘しました:

Stacktrace:

08-18 02:48:04.489  28893-28893/? E/WindowManager﹕ Activity com.ms.ha.fragment.FirstActivity has leaked window com.Android.internal.policy.impl.PhoneWindow$DecorView{52e58540 V.E..... R.....ID 0,0-1026,585} that was originally added here
    Android.view.WindowLeaked: Activity com.ms.ha.fragment.FirstActivity has leaked window com.Android.internal.policy.impl.PhoneWindow$DecorView{52e58540 V.E..... R.....ID 0,0-1026,585} that was originally added here
            at Android.view.ViewRootImpl.<init>(ViewRootImpl.Java:345)
            at Android.view.WindowManagerGlobal.addView(WindowManagerGlobal.Java:239)
            at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:69)
            at Android.app.Dialog.show(Dialog.Java:281)
            at com.ms.ha.fragment.TourGuideLoadURLFragment$WebAppInterface.moveToNextScreen(TourGuideLoadURLFragment.Java:116)
            at Android.webkit.WebViewCore.nativeMouseClick(Native Method)
            at Android.webkit.WebViewCore.nativeMouseClick(Native Method)
            at Android.webkit.WebViewCore.access$6800(WebViewCore.Java:59)
            at Android.webkit.WebViewCore$EventHub.dispatchWebKitEvent(WebViewCore.Java:1793)
            at Android.webkit.WebViewInputDispatcher.dispatchWebKitEvent(WebViewInputDispatcher.Java:689)
            at Android.webkit.WebViewInputDispatcher.dispatchWebKitEvents(WebViewInputDispatcher.Java:639)
            at Android.webkit.WebViewInputDispatcher.access$800(WebViewInputDispatcher.Java:78)
            at Android.webkit.WebViewInputDispatcher$WebKitHandler.handleMessage(WebViewInputDispatcher.Java:1153)
            at Android.os.Handler.dispatchMessage(Handler.Java:99)
            at Android.os.Looper.loop(Looper.Java:137)
            at Android.webkit.WebViewCore$WebCoreThread.run(WebViewCore.Java:814)
            at Java.lang.Thread.run(Thread.Java:841)

FirstActivity.Java:

 public class FirstActivity extends FragmentActivity  implements View.OnClickListener{

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.fragment_tour_guide_web);
  .......
  .......

   webView.addJavascriptInterface(new WebAppInterface(this), "Android");

 }


    public class WebAppInterface {
        Context mContext;

        /**
         * Instantiate the interface and set the context
         */
        WebAppInterface(Context c) {
            mContext = c;
        }

        /**
         * Intent - Move to next screen
         */

        @JavascriptInterface
        public void moveToNextScreen() {
            AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
                    context);

            // set title
            alertDialogBuilder.setTitle("Your Title");

            // set dialog message
            alertDialogBuilder
                    .setMessage("Click yes!")
                    .setCancelable(false)
                    .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {

                            Intent i = new Intent(FirstActivity.this,SecondActivity.class);
                            startActivity(i);
                        }
                    })
                    .setNegativeButton("No", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            // if this button is clicked, just close
                            // the dialog box and do nothing
                            dialog.cancel();
                        }
                    });

            // create alert dialog
            AlertDialog alertDialog = alertDialogBuilder.create();

            // show it
            alertDialog.show();  --->leak window error

        }

    }

  }

この問題を解決する方法がわかりません。

21
Steve

ProgressDialogが破棄されている間にActivityが実行されているため、エラーが発生します。新しいActivityを開始する前にダイアログを閉じる必要があります。

.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
  public void onClick(DialogInterface dialog, int id) {
      if (alertDialog != null && alertDialog.isShowing()) {
          alertDialog.dismiss();
      }
      Intent i = new Intent(FirstActivity.this, SecondActivity.class);
      startActivity(i);
  }
});

私はそれが役立つことを願っています!

46
Rajesh

OnPause()メソッドでalertDialogを閉じます。つまり、alertDialog.dismiss()を呼び出します

注:通常、アクティビティが終了する前にダイアログが閉じられない場合、WindowLeaked例外が発生します。

11
codevscolor

アクティビティが終了したら、ダイアログを閉じる/キャンセルする必要があります。通常、アクティビティが終了する前にダイアログが閉じられない場合に発生します。

2
Daud Arfin

また、ダイアログを表示しようとしたときにUIスレッドにいない場合は、WindowLeaked例外を取得することもできます。簡単な修正:

this.runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // show dialog here
    }
});
1
ScottyB