一、场景描述:
在开发中碰到这样的一个NullPointerException,activity中通过
TestFragment fragment = TestFragment.newInstance(model);
例子:
将model数据传入到fragment中。在正常情况下打开页面都正常。
public static TestFragment newInstance(Model model) {
TestFragment fragment = new TestFragment();
Bundle bundle = new Bundle();
bundle.putParcelable("model", model);
fragment.setArguments(bundle);
return fragment;
}
public class Model {
@Expose
public String id;
@Expose
public ModelBean modelBean;
}
二、出现NullPointerException分析:
在我们直接回到手机桌面,导致内存回收当前页面,再次打开,系统直接唤醒当前页面,会去出现NullPointerException。出现这个bug的原因是我的model数据中被用到的字段没有序列化,导致页面中用到的地方空指针。如上段例子中Model在activity之间传递,但是没有序列化,不重新唤醒该页面的时候这种写法没有问题,不会造成NullPointerException;
model.modelBean.xxx;
model.id;
如果我们在代码中有这样引用到这类的语句就会NullPointerException;
我们的fragment中将数据存在Bundle中,重新唤醒页面会从Bundle中取数据,这部分数据需要序列化,没有序列化就会NullPointerException;这里要注意ModelBean中的数据要是用的话,ModelBean里的数据也需要序列化。
public class Model implements Parcelable {
@Expose
public String id;
@Expose
public ModelBean modelBean;
protected TravelerBean(Parcel in) {
this.id = in.readString();
this.author = in.readParcelable(ModelBean.class.getClassLoader());
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.id);
dest.writeParcelable(this.modelBean, flags);
}
}
public class ModelBean implements Parcelable {
@Expose
public String xxx;
protected TravelerBean(Parcel in) {
this.xxx = in.readString();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.xxx);
}
public static final Creator<ModelBean> CREATOR = new Creator<ModelBean>() {
@Override
public ModelBean createFromParcel(Parcel in) {
return new ModelBean(in);
}
@Override
public ModelBean[] newArray(int size) {
return new ModelBean[size];
}
};
@Override
public int describeContents() {
return 0;
}
}
三、结论:
我碰到的重新唤醒这种情况也是需要序列化model中所有用到的字段,不序列化会导致NullPointerException。
网友评论