目录

前言

Why

怎么解决

How to 办?


前言

搞项目的时候遇到一个Bug,当ListPopupWindow显示的时候,按返回键就会报标题类似的错误。但是在点击Toolbar的NavigationIcon时(设置了finish的点击事件),却不会报这个窗体溢出的Bug。

Why

首先来了解下这个错误产生的原因(呃,网上说的很清楚了,我就直接复制了):

Android的每一个Activity都有个WindowManager窗体管理器,同样,构建在某个Activity之上的对话框、PopupWindow也有相应的WindowManager窗体管理器。但是它们不能脱离Activity而单独存在着,因为需要Activity的Context,所以当某个Dialog或者某个PopupWindow正在显示的时候我们干掉了承载该Dialog(或PopupWindow)的Activity,就会抛WindowLeaked异常了,因为这个Dialog(或PopupWindow)的WindowManager已经没有谁可以附属了(Context)。

怎么解决

既然问题原因知道了,好的,我解决起来不是很简单么,在Activity的OnDestroy方法里,如果popupWindow显示的话,我让它dismiss掉不就好了。嗯,就是这样,简单!

@Overrideprotected void onDestroy() {super.onDestroy();if(mMerchantPopupWindow!=null&&mMerchantPopupWindow.isShowing())mMerchantPopupWindow.dismiss();mMerchantPopupWindow=null;}

But,我被打脸了,还是报这个异常。
那么好,我在onBackPressed方法中让popup消失总可以了吧,然而,还是不行,还是被打脸了

How to 办?

怒,仔细分析下。现身吧,柯南。
1.为什么点击toolbar的icon时,不报这个错,同样是finish掉这个页面
搞起,搞起,搞事情,简直!
唔,原来ListPopupWindow里面默认是设置PopupWindow点击外面PopupWindow消失的。

mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch&& !mDropDownAlwaysVisible);

而这两个变量默认是false:

private booleanmDropDownAlwaysVisible=false;
private booleanmForceIgnoreOutsideTouch=false;

原来如此,点击icon的时候,popup先dismiss了,然后页面finish掉不会报错。
2.为什么我设置了按返回键后,在页面销毁时让popup消失,却不行呢?
再次搞事情。既然将一个Activity组件的应用程序窗口视图对象与一个ViewRoot对象关联是通过该Activity组件所使用的窗口管理器(WindowManager)来执行的。调用所获得的本地窗口管理器wm(类型为LocalWindowManager)的成员函数addView来执行关联应用程序窗口视图对象和ViewRoot对象的操作。
那么我们就来找一找WindowManager。
找到了!

mWindowManager = mWindow.getWindowManager();

嗯,来看下Window类:

public WindowManager getWindowManager() {return mWindowManager;
}
mWindowManager=((WindowManagerImpl)wm).createLocalWindowManager(this);

嗯,再来找下WindowManagerImpl:


public final class WindowManagerImpl implements WindowManager {private final WindowManagerGlobalmGlobal=WindowManagerGlobal.getInstance();public WindowManagerImplcreateLocalWindowManager(WindowparentWindow){return new WindowManagerImpl(mDisplay,parentWindow);
}@Overridepublic void addView(Viewview,ViewGroup.LayoutParamsparams){mGlobal.addView(view,params,mDisplay,mParentWindow);
}

嗯,看起来WindowManagerGlobal的嫌疑很大啊,小伙子,搞事情啊!WindowManagerGlobal#performStop

final void performStop() {....if(!mStopped) {...if(mToken!=null&&mParent==null) {WindowManagerGlobal.getInstance().setStoppedState(mToken,true);}...mInstrumentation.callActivityOnStop(this);...}
}

那么WindowManagerGlobal的setStoppedState又是啥呢?看这里。

 public void setStoppedState(IBinder token, boolean stopped) {synchronized (mLock) {int count = mViews.size();for (int i = 0; i < count; i++) {if (token == null || mParams.get(i).token == token) {ViewRootImpl root = mRoots.get(i);root.setWindowStopped(stopped);}}}}

再来看下ViewRootImpl的setWindowStoped方法:

  void setWindowStopped(boolean stopped) {if (mStopped != stopped) {mStopped = stopped;if (!mStopped) {scheduleTraversals();}}}

ViewRootImpl#mStopped 当Window状态为stoped时为true,代表Window不再活跃。


// Set to true if the owner of this window is in the stopped state,// so the window should no longer be active.boolean mStopped = false;

那么Activity#performStop方法啥时候调用的呢。再来看下前面的WindowManagerGlobal#performStop方法。
看到这句mInstrumentation.callActivityOnStop(this)没?
来看下Instrumentation#callActivityOnStop方法


public void callActivityOnStop(Activity activity) {activity.onStop();}

也就是说,执行完Activity#performStop方法会调用Activity#OnStop方法。在OnStop之前,performStop()就执行了。

窗体泄露 android.view.WindowLeaked: Activity XxxActivity has leaked window android.widget.PopupWindow$Po相关推荐

  1. android.view.WindowLeaked: Activity XXX has leaked window DecorView@9801a78[XXX] that was originall

    android.view.WindowLeaked: Activity XXXX has leaked window DecorView@9801a78[XXXX] that was original ...

  2. E/WindowManager: android.view.WindowLeaked: Activity com.xxx.xxx.xxx has leaked window com.android.i

    今天运行代码,程序没有崩溃,并遇到以下错误提示: E/WindowManager: android.view.WindowLeaked:Activity com.xxx.xxx.xxx has lea ...

  3. android.view.WindowLeaked: Activity com.xty.activity.ActivityMainPage has leaked window com.android.

    android.view.WindowLeaked: Activity com.xty.activity.ActivityMainPage has leaked window com.android. ...

  4. E/WindowManager: android.view.WindowLeaked: Activity com.xxx.xxx.xxx

    1. 错误描述 E/WindowManager: android.view.WindowLeaked: Activity com.xxx.xxx has leaked window DecorView ...

  5. android.view.WindowLeaked: Activity has leaked window com.android.internal.p

    android.view.WindowLeaked: Activity  has leaked window com.android.internal.policy.impl.PhoneWindow$ ...

  6. android.view.WindowLeaked: Activity com.xty.activity.ActivityMainPage has leaked window

    android.view.WindowLeaked: Activity com.xty.activity.ActivityMainPage has leaked window com.android. ...

  7. 关于android.view.WindowLeaked(窗体泄露)的解决方案

    虽然是小问题一个,但也困扰了我一段时间,现在记下来,给自己做个备忘,也可以给其他人一个参考 Java代码   view plaincopy to clipboardprint? 01-08 01:49 ...

  8. 关于android.view.WindowLeaked的解决方案

    虽然是小问题一个,但也困扰了我一段时间,现在记下来,给自己做个备忘,也可以给其他人一个参考 1.01-08 01:49:27.874: ERROR/WindowManager(473): Activi ...

  9. 关于android.view.WindowLeaked异常的解决方案

    虽然是小问题一个,但也困扰了我一段时间,现在记下来,给自己做个备忘,也可以给其他人一个参考. Android.view.WindowLeaked按字面了解,Window Leaked大概就是说一个窗体 ...

最新文章

  1. mysql工具navicat用户授权_Navicat使用教程:在Navicat Premium中管理MySQL用户 - 第4部分:权限管理器工具...
  2. 一个hadoop hdfs put 文件失败的小情况
  3. Linux入门和运维
  4. cp: omitting directory”错误
  5. HDU 4325 离散化+树状数组 或者 不使用树状数组
  6. drupal6 笔记
  7. 并查集(图论) LA 3644 X-Plosives
  8. 反向代理post参数怎么传输_面试必备:GET和POST的区别详细解说
  9. mysql整站源码安装_MySQL入门01-MySQL源码安装
  10. 为什么在python中整数的值没有限制_python-为什么math.log接受大整数值?
  11. 清官谈mysql中utf8和utf8mb4区别
  12. win2008r2 or centos6 硬盘挂载
  13. mysql读写分离错_MySQL主从同步、读写分离配置步骤、问题解决
  14. ruby分割字符串_Ruby中常用的字符串处理函数使用实例
  15. 破解滑块验证码(打码平台)
  16. 华为认证 HCNA­Cloud 云计算题库
  17. 【S-V信道】基于毫米波的5G通信S-V信道模型仿真
  18. 新榜微信文章抓取客户端(APSpider)
  19. java bl层,科普一下bl锁的知识,没解锁的必看!
  20. IIS发布网站,如此简单

热门文章

  1. Java基础语法-21-02-22
  2. java list的contains,list的contains方法
  3. 微信公众号和小程序(一)
  4. dell笔记本c语言系统,戴尔Latitude 5280笔记本如何将自带win10改成win7
  5. 【GDOI模拟】妮厨的愤怒
  6. 计算机产品的特点是什么意思,笔记本电脑的优点是什么 笔记本电脑的缺点是什么...
  7. vmware fusion下win7分辨率自动切换解决办法
  8. 医咖会免费STATA教程学习笔记——多元线性回归
  9. c语言:编写程序,把你的名和姓打印在一行,然后把名和姓各打印一行。
  10. 8.13无限火力服务器维护到什么时候,LOL8.13版本的无限火力模式持续多长时间,什么时候结束?...