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

2024-06-15 15:32

本文主要是介绍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
             mContext = contentView.getContext();
284
             mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
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
         mContentView = contentView;
382
 
383
         if (mContext == null) {
384
             mContext = mContentView.getContext();
385
         }
386
 
387
         if (mWindowManager == null) {
388
             mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
389
         }
390
     }
 
同是
Step 4 :
4.0.4 系统下
390
     public void setContentView(View contentView) {
391
         if (isShowing()) {
392
             return;
393
         }
394
 
395
         mContentView = contentView;
396
 
397
         if (mContext == null && mContentView != null) {
398
             mContext = mContentView.getContext();
399
         }
400
 
401
         if (mWindowManager == null && mContentView != null) {
402
             mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
403
         }
404
     }
果然~出现了非常神奇的一幕~ 原来在2.3.3的时候忘记检查
mContentView 是否为空,因为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

转载请说明出处,鼓励原创!

这篇关于PopWindow在Android 2.3.3 或以下的系统的一个bug 及其解决办法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1063851

相关文章

Mac系统下卸载JAVA和JDK的步骤

《Mac系统下卸载JAVA和JDK的步骤》JDK是Java语言的软件开发工具包,它提供了开发和运行Java应用程序所需的工具、库和资源,:本文主要介绍Mac系统下卸载JAVA和JDK的相关资料,需... 目录1. 卸载系统自带的 Java 版本检查当前 Java 版本通过命令卸载系统 Java2. 卸载自定

基于Python实现一个简单的题库与在线考试系统

《基于Python实现一个简单的题库与在线考试系统》在当今信息化教育时代,在线学习与考试系统已成为教育技术领域的重要组成部分,本文就来介绍一下如何使用Python和PyQt5框架开发一个名为白泽题库系... 目录概述功能特点界面展示系统架构设计类结构图Excel题库填写格式模板题库题目填写格式表核心数据结构

Linux系统中的firewall-offline-cmd详解(收藏版)

《Linux系统中的firewall-offline-cmd详解(收藏版)》firewall-offline-cmd是firewalld的一个命令行工具,专门设计用于在没有运行firewalld服务的... 目录主要用途基本语法选项1. 状态管理2. 区域管理3. 服务管理4. 端口管理5. ICMP 阻断

Android学习总结之Java和kotlin区别超详细分析

《Android学习总结之Java和kotlin区别超详细分析》Java和Kotlin都是用于Android开发的编程语言,它们各自具有独特的特点和优势,:本文主要介绍Android学习总结之Ja... 目录一、空安全机制真题 1:Kotlin 如何解决 Java 的 NullPointerExceptio

Windows 系统下 Nginx 的配置步骤详解

《Windows系统下Nginx的配置步骤详解》Nginx是一款功能强大的软件,在互联网领域有广泛应用,简单来说,它就像一个聪明的交通指挥员,能让网站运行得更高效、更稳定,:本文主要介绍W... 目录一、为什么要用 Nginx二、Windows 系统下 Nginx 的配置步骤1. 下载 Nginx2. 解压

如何确定哪些软件是Mac系统自带的? Mac系统内置应用查看技巧

《如何确定哪些软件是Mac系统自带的?Mac系统内置应用查看技巧》如何确定哪些软件是Mac系统自带的?mac系统中有很多自带的应用,想要看看哪些是系统自带,该怎么查看呢?下面我们就来看看Mac系统内... 在MAC电脑上,可以使用以下方法来确定哪些软件是系统自带的:1.应用程序文件夹打开应用程序文件夹

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.

使用Python实现Windows系统垃圾清理

《使用Python实现Windows系统垃圾清理》Windows自带的磁盘清理工具功能有限,无法深度清理各类垃圾文件,所以本文为大家介绍了如何使用Python+PyQt5开发一个Windows系统垃圾... 目录一、开发背景与工具概述1.1 为什么需要专业清理工具1.2 工具设计理念二、工具核心功能解析2.

Linux系统之stress-ng测压工具的使用

《Linux系统之stress-ng测压工具的使用》:本文主要介绍Linux系统之stress-ng测压工具的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、理论1.stress工具简介与安装2.语法及参数3.具体安装二、实验1.运行8 cpu, 4 fo

ubuntu20.0.4系统中安装Anaconda的超详细图文教程

《ubuntu20.0.4系统中安装Anaconda的超详细图文教程》:本文主要介绍了在Ubuntu系统中如何下载和安装Anaconda,提供了两种方法,详细内容请阅读本文,希望能对你有所帮助... 本文介绍了在Ubuntu系统中如何下载和安装Anaconda。提供了两种方法,包括通过网页手动下载和使用wg