首页 文章

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

提问于
浏览
989

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

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)

30 回答

  • 2

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

  • 5

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

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

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

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

  • 11

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

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

  • 5

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

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

  • 105

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

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

    android:noHistory="true"
    

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

  • 376
    if (mActivity != null && !mActivity.isFinishing() && mProgressDialog != null && mProgressDialog.isShowing()) {
            mProgressDialog.dismiss();
        }
    
  • 53

    我错误地在 AlertDialog 上调用 hide() 而不是 dismiss() 来触发此错误 .

  • 12

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

    // 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();
                    }
                }
    
  • 5

    如果您在 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();
    
  • 4

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

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

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

    [EDIT]

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

    Answer 1

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

    Answer 2

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

    Answer 3

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

  • 1

    解决方法是在退出 Activity 之前在 viewP.java:183 中创建的 Dialog 上调用 dismiss() ,例如在 onPause() . 所有 Window s& Dialog 应该在离开 Activity 之前关闭 .

  • 1

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

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

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

  • 30

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

    因此,简单地调用 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(); 之后调用它一样,因此它会说窗口被泄露了通过在对话框出现后完成,即使情况并非如此,它仍然认为是 .

    我以为我会在这里添加这个,因为这表明结束命令的行为不同然后我认为它确实如此,我猜其他人在我发现这个之前就像我一样 .

  • 2

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

    @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 仍然显示!

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

  • 2

    Best solution is just add dialog in try catch and dismiss dialog when exception occur

    只需使用下面的代码

    try {
            dialog.show();
        } catch (Exception e) {
            dialog.dismiss();
        }
    
  • 3

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

    Example:

    OldActivity instance;
    
        oncreate() {
           instance=this;
        }
        instance.finish();
        instance.startActivity(new Intent(ACTION_MAIN).setClass(instance, NewActivity.class));
    
  • 15

    这可能有所帮助 .

    if (! isFinishing()) {
    
        dialog.show();
    
        }
    
  • 4

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

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

    It could be, that your app crashed for some other reason while your dialog was open

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

    So, look through your logical. Solve the first error, and then the second error will solve itself

    One error causes another, which causes another, like DOMINOS!

  • 11

    活动销毁时关闭对话框

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        if (pDialog!=null && pDialog.isShowing()){
            pDialog.dismiss();
        }
    }
    
  • 5

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

  • 4

    你必须在 AsyncTaskonPreExecute 方法中创建 Progressdialog 对象,你应该在 onPostExecute 方法上 dismiss 它 .

  • 52

    我在我的视频播放器应用程序中获取这些日志 . 视频播放器关闭时抛出这些消息 . 有趣的是,我曾经以随机方式在几次运行中获取这些日志 . 我的申请也不涉及任何 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();
    }
    

    通过调用 mVideoView.pause() 覆盖 OnPause 并将 visibility 设置为 GONE . 这样我就可以解决“ Activity has leaked window ”日志错误问题 .

  • 1

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

    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();
    }
    }
    
  • 19

    当我在 AsyncTask 中使用 ProgressDialog 时,这发生在我身上 . 其实我在 onPostExecute 中使用 hide() 方法 . 根据@Alex Volovoy的答案,我需要使用 dismiss()ProgressDialog 在onPostExecute中删除它并完成它 .

    progressDialog.hide(); // Don't use it, it gives error
    
    progressDialog.dismiss(); // Use it
    
  • 1341

    最佳解决方案是在显示 progressbarprogressDialog 之前

    if (getApplicationContext().getWindow().getDecorView().isShown()) {
    
      //Show Your Progress Dialog
    
    }
    
  • 9

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

  • 6

    Activity 实际上是 finished 后尝试显示警报时,会出现“ Activity has leaked window that was originally added... ”错误 .

    你有两个选择AFAIK:

    • 重新考虑警报的登录:在实际退出活动之前,在 dialog 上调用 dismiss() .

    • dialog 放在另一个线程中并在 thread 上运行它(与当前 activity 无关) .

  • 10

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

    try {
            if (null != progressDialog && progressDialog.isShowing()) {
                progressDialog.dismiss();
                progressDialog = null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    
  • 3

    试试这段代码:

    public class Sample extends Activity(){
    @Override
     public void onCreate(Bundle instance){
    
    }
     @Override
        public void onStop() {
            super.onStop();
          progressdialog.dismiss(); // try this
        }
    
    }
    

相关问题