活动已泄露最初添加的窗口

android memory-leaks dialog

436351 观看

30回复

127444 作者的声誉

这是什么错误,为什么会发生?

05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850):     at dalvik.system.NativeStart.main(Native Method)
作者: Pentium10 的来源 发布者: 2010 年 5 月 17 日

回应 (30)


1330

56532 作者的声誉

决定

您在退出活动后尝试显示对话框。

[编辑]

这个问题是google for android开发者的热门搜索之一,因此从评论中添加了一些重要的观点,这可能对未来的调查人员更有帮助,而无需进行深入的评论对话。

答案1

您在退出活动后尝试显示对话框。

答案2

在某些情况下这个错误可能有点误导(尽管答案仍然是完全准确的) - 即在我的情况下,在AsyncTask中抛出了未处理的异常,导致Activity关闭,然后打开progressdialog导致此异常..所以“真正的”例外在日志中早一点

答案3

在退出Activity之前调用您创建的Dialog实例上的dismiss(),例如onPause()或onDestroy()

作者: Alex Volovoy 发布者: 17.05.2010 03:54

377

8704 作者的声誉

解决的办法是打电话给dismiss()Dialog您创建viewP.java:183退出之前Activity,例如onPause()。所有的Windows&Dialogs应该在离开之前关闭Activity

作者: molnarm 发布者: 17.05.2010 06:50

103

4752 作者的声誉

如果您正在使用AsyncTask,可能该日志消息可能具有欺骗性。如果你在你的日志中查找,你可能会发现另一个错误,可能是你的doInBackground()方法中的一个错误,AsyncTask即让你的当前Activity爆炸,因此一旦AsyncTask回来......好吧,你知道其余的。其他一些用户已在此处解释:-)

作者: ggomeze 发布者: 20.07.2010 06:23

52

1083 作者的声誉

你可以通过一个简单/愚蠢的错误来获得这个异常,例如,如果你在switch语句中错过了一个break调用语句,那么finish()在显示之后意外调用AlertDialog...

   @Override
   public void onClick(View v) {
    switch (v.getId()) {
        case R.id.new_button:
            openMyAlertDialog();
            break; <-- If you forget this the finish() method below 
                       will be called while the dialog is showing!
        case R.id.exit_button:
            finish();
            break;
        }
    }

finish()方法将关闭Activity,但AlertDialog仍然显示!

因此,当你专心盯着代码,寻找糟糕的线程问题或复杂的编码等时,不要忽视森林中的树木。有时它可能只是一个简单而愚蠢的东西,就像一个缺失的断言。:)

作者: Adrian Romanelli 发布者: 08.10.2010 08:48

11

1630 作者的声誉

我有同样晦涩的错误信息,不知道为什么。根据之前答案的线索,我将我的非GUI调用mDialog.finish()更改为mDialog.dismiss(),错误消失了。这并没有影响我的小部件的行为,但它令人不安,很可能已经标记了一个重要的内存泄漏。

作者: Melinda Green 发布者: 27.03.2011 05:49

10

711 作者的声誉

我遇到了同样的问题并找到了这个页面,虽然我的情况不同,但在定义警报框之前我finish从一个if块调用。

因此,简单地调用dismiss不起作用(因为它尚未制作)但是在阅读了Alex Volovoy的回答并意识到它是导致它的警报框之后。我尝试在该if块内完成后立即添加一个return语句并修复了该问题。

我想,一旦你打完了它就停止了一切并完成了那里,但事实并非如此。它似乎到了它所在的代码块的末尾然后完成。

所以,如果你想要实现一种情况,有时它会在完成一些代码之前完成,你必须在完成之后立即放置一个return语句,否则它将继续运行并且就像在结束时调用结束一样。不在你调用它的地方的代码块。这就是为什么我得到了所有那些奇怪的错误。

private picked(File aDirectory){
     if(aDirectory.length()==0){
        setResult(RESULT_CANCELED, new Intent()); 
        finish(); 
        return;
    }
     AlertDialog.Builder alert= new AlertDialog.Builder(this); // Start dialog builder
     alert
        .setTitle("Question")
        .setMessage("Do you want to open that file?"+aDirectory.getName());
    alert
        .setPositiveButton("OK", okButtonListener)
        .setNegativeButton("Cancel", cancelButtonListener);
    alert.show();
}

如果你在我在那里调完完之后没有把它放回去,那就好像你已经在它之后调用了它alert.show();,因此它会说你在对话框出现后就完成了窗口泄露,即使那是不是这样,它仍然认为是。

我想我会在这里添加这个,因为这显示了完成命令的行为不同然后我认为它确实如此,我猜有其他人在我发现这个之前就像我一样。

作者: Kit Ramos 发布者: 08.08.2011 12:57

51

1091 作者的声誉

我被误调用触发此错误的hide(),而不是dismiss()AlertDialog

作者: Mark Phillip 发布者: 07.12.2011 07:29

19

1077 作者的声誉

我最近遇到了同样的问题。

这个问题背后的原因是在关闭对话框之前关闭了活动。上述情况有多种原因。上面帖子中提到的那些也是正确的。

我遇到了一种情况,因为在线程中,我正在调用一个抛出异常的函数。因为窗户被解雇,因此例外。

作者: Tushar 发布者: 08.12.2011 09:12

11

134 作者的声誉

我在我的视频播放器应用程序中获取这些日志。视频播放器关闭时抛出这些消息。有趣的是,我曾经以随机方式在几次运行中获取这些日志。我的申请也不涉及任何progressdialog。最后,我通过以下实现解决了这个问题。

@Override
protected void onPause()
{
    Log.v("MediaVideo", "onPause");
    super.onPause();
    this.mVideoView.pause();
    this.mVideoView.setVisibility(View.GONE);
}

@Override
protected void onDestroy()
{
    Log.v("MediaVideo", "onDestroy");
    super.onDestroy();
}

@Override
protected void onResume()
{
    Log.v("MediaVideo", "onResume");
    super.onResume();
    this.mVideoView.resume();
}

覆盖OnPausewith调用mVideoView.pause()和设置visibilityGONE。这样我就可以解决“ Activity has leaked window”日志错误问题。

作者: InvisiblePoint 发布者: 26.06.2012 01:54

5

28634 作者的声誉

Activity has leaked window that was originally added...当您尝试在Activity有效后显示警报时,会出现“ ”错误finished

你有两个选择AFAIK:

  1. 重新考虑你的警报的登录:调用dismiss()dialog实际退出你的活动之前。
  2. 将其dialog置于不同的线程并在其上运行thread(独立于当前activity)。
作者: Kyle Clegg 发布者: 13.08.2012 03:29

30

546 作者的声誉

在退出活动后尝试显示对话框时出现此问题。

我刚刚通过写下以下代码解决了这个问题:

@Override
public void onDestroy(){
    super.onDestroy();
    if ( progressDialog!=null && progressDialog.isShowing() ){
        progressDialog.cancel();
    }
}

基本上,从哪个类开始progressDialog,覆盖onDestroy方法并以这种方式执行。它解决了“活动已泄露窗口”的问题。

作者: Shoaib Ahmed 发布者: 30.08.2012 06:55

3

7600 作者的声誉

在我的情况下,原因是我忘了在Android清单文件中包含权限。

我是怎么知道的?好吧,就像@Bobby在接受的答案下面的评论中说的那样,只需向上滚动到你的日志,你就会看到真正抛出异常的第一个原因或事件。显然,消息“活动已泄漏最初添加的窗口”只是一个异常,它是由第一个异常引起的。

作者: Matt Quiros 发布者: 08.09.2012 05:05

6

310 作者的声誉

不仅尝试显示警报,还可以在完成特定活动实例并尝试启动新活动/服务或尝试停止时调用它。

例:

OldActivity instance;

    oncreate() {
       instance=this;
    }
    instance.finish();
    instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));
作者: Kulbhushan Chaskar 发布者: 04.03.2013 10:35

4

1636 作者的声誉

如果仍然显示ProgressDialog,我在完成活动的问题。

首先隐藏对话框,然后完成活动。

作者: LeonS 发布者: 06.03.2013 06:36

5

319 作者的声誉

试试这段代码:

public class Sample extends Activity(){
@Override
 public void onCreate(Bundle instance){

}
 @Override
    public void onStop() {
        super.onStop();
      progressdialog.dismiss(); // try this
    }

}
作者: tinku 发布者: 27.03.2013 10:25

9

2544 作者的声誉

这可能有所帮助。

if (! isFinishing()) {

    dialog.show();

    }
作者: sandy 发布者: 26.04.2013 09:47

4

51 作者的声誉

你必须ProgressdialogonPreExecute方法中创建对象AsyncTask,你应该dismissonPostExecute方法上。

作者: ammad 发布者: 24.05.2013 11:40

10

14062 作者的声誉

活动销毁时关闭对话框

@Override
protected void onDestroy()
{
    super.onDestroy();
    if (pDialog!=null && pDialog.isShowing()){
        pDialog.dismiss();
    }
}
作者: Muhammad Aamir Ali 发布者: 27.06.2013 11:56

5

4108 作者的声誉

这可能是因为你在doInBackground()函数中有错误并且有这个代码。

尝试最后添加对话框。首先检查并修复doInBackground()功能

protected void onPreExecute() {
     super.onPreExecute();
     pDialog = new ProgressDialog(CreateAccount.this);
     pDialog.setMessage("Creating Product..");
     pDialog.setIndeterminate(false);
     pDialog.setCancelable(true);
     pDialog.show();

 }

 protected String doInBackground(String...args) {
     ERROR CAN BE IS HERE
 }

 protected void onPostExecute(String file_url) {
     // dismiss the dialog once done
     pDialog.dismiss();
作者: NickUnuchek 发布者: 20.07.2013 07:10

1

121 作者的声誉

由于代码中某处出现了一些异常,请确保您的活动未意外关闭。通常,当活动面临强制关闭doinBackground方法然后asynctask返回onPostexecute方法时,它发生在异步任务中。

作者: Manas Ranjan 发布者: 16.12.2013 09:26

2

541 作者的声誉

尝试下面的代码,它将在您解除进度对话框的任何时候工作,它将查看其实例是否可用。

try {
        if (null != progressDialog && progressDialog.isShowing()) {
            progressDialog.dismiss();
            progressDialog = null;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
作者: Developer 发布者: 14.02.2014 06:16

2

276 作者的声誉

窗口泄露异常有两个原因:

1)当Activity Context不存在时显示对话框,要解决此问题,您应该只显示对话框,确定Activity存在:

if(getActivity()!= null && !getActivity().isFinishing()){
        Dialog.show();
}

2)不要适当地关闭对话框,解决使用此代码:

@Override
public void onDestroy(){
    super.onDestroy();
    if ( Dialog!=null && Dialog.isShowing() ){
        Dialog.dismiss();
}
}
作者: Sherry 发布者: 17.09.2015 08:09

5

3653 作者的声誉

这发生在我身上,当我使用ProgressDialogAsyncTask。其实我正在使用hide()方法onPostExecute。基于@Alex Volovoy的答案,我需要使用dismiss()with ProgressDialog在onPostExecute中删除它并完成它。

progressDialog.hide(); // Don't use it, it gives error

progressDialog.dismiss(); // Use it
作者: SANAT 发布者: 19.02.2016 05:29

7

1767 作者的声誉

这不是问题的答案,但它与该主题相关。

如果活动在Manifest中定义了一个属性

 android:noHistory="true"

然后在执行onPause()之后,活动的上下文就会丢失。因此,使用上下文的所有视图都可能会出现此错误。

作者: Killer 发布者: 09.05.2016 02:25

1

554 作者的声誉

  if (mActivity != null && !mActivity.isFinishing() && mProgressDialog != null && mProgressDialog.isShowing()) {
        mProgressDialog.dismiss();
    }
作者: androidmalin 发布者: 27.06.2016 02:17

1

315 作者的声誉

根据我的问题是你试图在一个活动完成后立即调用一个对话框,所以根据我你可以做的是使用Handler给你一些延迟,你的问题将解决,例如:

 Handler handler=new Handler();
     handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                     dialog.show();
                     //or
                     dialog.dismiss();

                }
            },100);
作者: Satish Silveri 发布者: 08.12.2016 06:41

15

3438 作者的声誉

这个问题的答案都是正确的,但实际上我理解为什么有点令人困惑。玩了大约2个小时后,这个错误的原因(在我的情况下)打了我:

通过阅读其他答案,您已经知道有X has leaked window DecorView@d9e6131[]错误意味着当您的应用关闭时对话框已打开。但为什么?

可能是,当您的对话框打开时,您的应用程序因某些其他原因而崩溃

这会导致您的应用关闭,因为代码中存在一些错误,导致对话框因应用程序因其他错误而关闭的同时保持打开状态。

所以,看看你的逻辑。解决第一个错误,然后第二个错误将自行解决在此输入图像描述

一个错误导致另一个错误,导致另一个错误,如DOMINOS!

作者: Ruchir Baronia 发布者: 27.06.2017 12:31

4

566 作者的声誉

通常由于进度对话框而发生此问题:您可以通过在活动中使用以下任一方法来解决此问题:

 // 1):
          @Override
                protected void onPause() {
                    super.onPause();
                    if ( yourProgressDialog!=null && yourProgressDialog.isShowing() )
                  {
                        yourProgressDialog.cancel();
                    }
                }

       // 2) :
         @Override
            protected void onDestroy() {
                super.onDestroy();
                if ( yourProgressDialog!=null && yourProgressDialog.isShowing()
               {
                    yourProgressDialog.cancel();
                }
            }
作者: Bapusaheb Shinde 发布者: 15.09.2017 10:07

3

1141 作者的声誉

最佳解决方案是在发生异常时在try catch和dismiss对话框中添加对话框

只需使用下面的代码

 try {
        dialog.show();
    } catch (Exception e) {
        dialog.dismiss();
    }
作者: Ness Tyagi 发布者: 01.11.2017 09:56

2

601 作者的声誉

最好的解决方案是在显示progressbar或之前放置progressDialog

if (getApplicationContext().getWindow().getDecorView().isShown()) {

  //Show Your Progress Dialog

}
作者: Ali Akram 发布者: 29.06.2018 06:45
32x32