自定义Dialog在外部赋值时空指针异常解决办法以及源码原因分析

30 篇文章 0 订阅

问题描述

在项目中,需要创建一个自定义的dialog,然后在外部对于dialog的控件进行赋值,此时发现空指针异常。

如下所示

这个是dialog的java文件,很简单就是里面有一个textview,然后在外部向textview赋值。

public class MyDialog extends Dialog {
    private Context context;
    private TextView tipsView;

    public TimeConflictDialog(Context context) {
        super(context);
        this.context = context;
    }

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_time_conflict);
        initView();
    }

    private void initView() {
        tips = findViewById(R.id.tv_tips);
    }

    public void setData(String str) {
        tips.setText(str);
    }
}

这里是外部调用的方式。

public class MyDialog extends Dialog {
    private Context context;
    private TextView tipsView;

    public TimeConflictDialog(Context context) {
        super(context);
        this.context = context;
    }

    @Override protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_time_conflict);
        initView();
    }

    private void initView() {
        tips = findViewById(R.id.tv_tips);
    }

    public void setData(String str) {
        tips.setText(str);
    }
}

这是外部创建,赋值并显示的代码

		MyDialog dialog =new MyDialog(this);
		dialog.setData("111");
		dialog.show();
        

此时会报空指针异常的情况。

原因分析

 

根据在setData调用控件的时候出现空指针异常,应该就是onCreate和setData的执行顺序的问题。setData的时候,onCreate中的控件还没有加载布局,自然控件指向null。接下来验证猜想。

此时点开dialog.show的源码,可以看到如下的源码。

public void show() {
        if (mShowing) {
            if (mDecor != null) {
                if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                    mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
                }
                mDecor.setVisibility(View.VISIBLE);
            }
            return;
        }

        mCanceled = false;

        if (!mCreated) {
            dispatchOnCreate(null);
        } else {
            // Fill the DecorView in on any configuration changes that
            // may have occured while it was removed from the WindowManager.
            final Configuration config = mContext.getResources().getConfiguration();
            mWindow.getDecorView().dispatchConfigurationChanged(config);
        }
        onStart();
        ……
    }

首先会判断是否正在显示,接着判断是否已创建dialog,如果没有调用dispatchOnCreate,这个方法内部会调用onCreate。此时再回看我们之前的调用顺序,先调用了setData,再show,自然此时onCreate还没调用,所以才会导致空指针异常。

所以如果想要正常实现,需要先调用show方法,再调用setData。虽然我觉得有点不太合理,按理来说应该是数据全部赋值完毕,控件初始化完成后,再展示dialog。但是源码中是在show中创建dialog,所以只能这样实现。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值