PopWindow在Android 2.3.3 或以下的系统的一个bug 及其解决办法

今日终于修复了一个非常严重的bug:
      这个bug非常奇怪,我在Anroid.4.0.4或以上测试都正常,但是后来廉温说他在他的手机按一下右下角的"设置"按钮(Button),居然出现了崩溃现象(理论上会在设置按钮上弹出一popuwindow);
     廉温手机系统2.3.X ;然后我用平板(系统也是2.3.x)测试下,果然出现错误;
     由于平板基本报废,无法USB连接地电脑跟踪测试;一开始我没放在心上,因为几台4.0.4or以上系统都测试能正常。。
     于是开了模拟器(系统2.3.3)测试,结果还是崩溃,看log日志 ,报了一个NullPointExcetion,这。。实在太费解了!
问题入口:
......
protected PopupWindow window;
......
this.window = new PopupWindow(ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT);
....
这里我实例化一个 PopupWindow ,当时我没有注意,以为传入2个 MeasureSpec (  Width/Height )也就是窗体layout_height 和layout_weight ; 可以是   FILL_PARENT or  WRAP_CONTENT or 具体的高和宽!
悲剧的是,看回文档,居然是:

public PopupWindow (int width, int height)
Added in  API level 1

Create a new empty, non focusable popup window. The dimension of the window must be passed to this constructor.

The popup does not provide any background. This should be handled by the content view.

Parameters
width the popup's width
height the popup's height 

这实际上要是指定了content view 的高、宽 而不是MeasureSpec (FILL_PARENT or WRAP_CONTENT 。。)
那就奇怪了,由于 ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT 这两个常量是负数
窗体的高宽是负数,按道理是不会显示窗体的啊!而且4.0.4系统还是会个跟2.3.3报同一个错误啊! 
但为啥在系统是4.0.4的时候还是正常显示,而2.3.3却错误?
于是我翻看了源码,跟踪记录如下:
Step 1: 
249
     public PopupWindow(int widthint height) {
250
         this(nullwidthheight);     
251
     } 
        

Step    2:
 
265
     public PopupWindow(View contentViewint widthint height) {
266
         this(contentViewwidthheightfalse);  // ->
contentView = null
267
     }
   
   
Step 3:
   
   
281
     public PopupWindow(View contentViewint widthint heightboolean focusable) {
282
         if (contentView != null) {
283
              = contentView.getContext();
285
         }
286
         setContentView(contentView);     // -> 在这里报了个NullPointExcetion ,再跟踪
287
         setWidth(width);
288
         setHeight(height);
289
         setFocusable(focusable);
290
     }


 Step 4 :
2.3.3
系统下
 
 
   
   
376
     public void setContentView(View contentView) {
377
         if (isShowing()) {
378
             return;
379
         }
380
 
381
          = contentView;
382
 
383
         if ( == null) {
384
              = .getContext();
385
         }
386
 
387
         if ( == null) {
389
         }
390
     }

   
   
 
同是
     
     
Step 4 :
4.0.4 系统下
390
     public void setContentView(View contentView) {
391
         if (isShowing()) {
392
             return;
393
         }
394
 
395
          = contentView;
396
 
397
         if ( == null &&  != null) {
398
              = .getContext();
399
         }
400
 
401
         if ( == null &&  != null) {
403
         }
404
     }

      
      
果然~出现了非常神奇的一幕~ 原来在2.3.3的时候忘记检查
 是否为空,因为mContextView 这个对象可以在实例化一个PopupWindow 后再通过SetContextView(View view)传入
也就是说,这是算是一个系统级的小bug~ 所以在2.3.3 或以前的版本时 就会崩溃,在4.0.4 以后的都不会崩溃;这不能完全怪谷歌,谁让我没有认真看下文档呢?
这也是我第一次发现谷歌的代码漏洞XD

解决2.3.3或以下的办法就是用
1、可以用PopupWindow(Context context)这个构造方法实例化
2、mPopupWindow.setContentView(View view) 传入content view
3、 mPopupWindow.setWidth(WindowManager.LayoutParams.WRAP_CONTENT);
mPopupWindow. setHeight(WindowManager.LayoutParams.WRAP_CONTENT);
这里的setWidth() setHeight() 才是是 改变PopupWindow 的Width/Height MeasureSpec

转载请说明出处,鼓励原创!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值