关于Android中PopupWindow在2.3以下使用出现NullPointerException的情况分析

关于Android中PopupWindow在2.3以下使用出现NullPointerException的情况分析

作者:CM 时间:2014-06-28 分类:Android 评论:0条 浏览:1107

今天有朋友在群里说继承PopupWindow华为手机测试的时候实例化PopupWindow出现NullPointerException的错误。具体代码如下:

public class MyPopup extends PopupWindow {
	private Context mContext;
	public MyPopup(Context context){
		this.mContext = context;
	}
}

错误信息如下:
11111

在其他手机上运行是正常的,开始以为是华为手机的问题后来发现这款华为手机系统是2.3的其他的都是2.3以上的,于是用2.3的模拟器运行了一次也出现错误了,看来是系统版本的问题。经过一整Google后发现网上也有人遇到这个问题,解决办法是在构造方法里加上super(context);

public class MyPopup extends PopupWindow {
	private Context mContext;
	public MyPopup(Context context){
		super(context);
		this.mContext = context;
	}
}

这样即可解决在2.3上以下出现NullPointerException的情况了。问题是解决了,可是是为什么呢?接下来我们分析以下。
当我们继承PopupWindow后new一个MyPopup的时候首先会调用PopupWindow的构造方法:

 public PopupWindow() {
        this(null, 0, 0);
    }

然后继续:

    public PopupWindow(View contentView, int width, int height) {
        this(contentView, width, height, false);
    }

继续跟下去:

    public PopupWindow(View contentView, int width, int height, boolean focusable) {
        if (contentView != null) {
            mContext = contentView.getContext();
            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        setContentView(contentView);
        setWidth(width);
        setHeight(height);
        setFocusable(focusable);
    }

然后我们看setContentView里面:

     public void setContentView(View contentView) {
        if (isShowing()) {
            return;
        }

        mContentView = contentView;

        if (mContext == null) {
            mContext = mContentView.getContext();
        }

        if (mWindowManager == null) {
            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        }
    }

相信大家都看到问题所在了,这里的context是null,然后执行了mContext = mContentView.getContext()而contentview我们还没有设置也为null,所以报NullPointerException。而加上super(context)后实例化PopupWindow的时候调用的是PopupWindow的:

 public PopupWindow(Context context) {
        this(context, null);
    }

故不会出现问题。
接下来我们再来看一下4.0的setContentView:

      public void setContentView(View contentView) {
        if (isShowing()) {
            return;
        }

        mContentView = contentView;

        if (mContext == null && mContentView != null) {
            mContext = mContentView.getContext();
        }

        if (mWindowManager == null && mContentView != null) {
            mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
        }
    }

4.0的多加了一个contentview的非空判断,所以4.0以上的没有问题。

相关推荐
更多

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>