【问题标题】:Activity has leaked window at alertDialog show() methodActivity 在 alertDialog show() 方法处泄漏了窗口
【发布时间】:2018-08-29 03:16:10
【问题描述】:

由于使用 AlertDialog,我在运行时遇到窗口泄漏错误。

我已经指出了下面代码中的错误行:

堆栈跟踪:

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

        }

    }

  }

我不知道如何解决这个问题。

【问题讨论】:

  • 当您尝试显示/关闭在一个 Activity 中创建和显示并在另一个 Activity 中关闭的 ALertDialog 时会发生这种情况。

标签: android android-alertdialog


【解决方案1】:

您收到错误是因为 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);
  }
});

希望对你有帮助!

【讨论】:

  • 尝试我在答案中编辑的代码。新活动开始时关闭对话框或完成活动
  • 这意味着您的主线程不知道您的更改,然后当它采取行动时,您的主线程发现它已经是不同的对象。尝试在主线程中调用你的函数。` runOnUiThread(new Runnable() { @Override public void run() { //你的函数 } });`
  • 但在这种情况下,stacktrace 应该在onStop()onDestroy() 上有泄漏,不是吗?
【解决方案2】:

关闭 onPause() 方法中的 alertDialog。即调用 alertDialog.dismiss()

注意:如果在 Activity 结束之前没有关闭对话框,通常会发生 WindowLeaked 异常。

【讨论】:

    【解决方案3】:

    如果您在尝试显示对话框时不在 UI 线程中,也可能会收到 WindowLeaked 异常。轻松修复:

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

    【讨论】:

      【解决方案4】:

      活动结束后,您必须关闭/取消对话。如果在 Activity 结束之前没有关闭对话框,通常会发生这种情况。

      【讨论】:

        【解决方案5】:

        如果您已设置互联网权限,请检查您的清单:

        <uses-permission android:name="android.permission.INTERNET" />
        

        【讨论】:

          【解决方案6】:

          我不知道这是否有帮助,但对我来说,问题导致了 multidex。 在 build.gradle

          multiDexEnabled false
          

          【讨论】:

          • 不,multidex 不适用于这里! =0
          猜你喜欢
          • 1970-01-01
          • 2017-01-12
          • 2012-02-14
          • 1970-01-01
          • 1970-01-01
          • 2011-02-20
          • 1970-01-01
          相关资源
          最近更新 更多