Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

when i use parcelable interface to read/write a Boolean, Nullobject Reference happens,why?

Tags:

java

android

I'm trying to make an object Parcelable in order to pass to an activity I start writing a Userclass implementing Parcelable.

one attributes of Userare is boolean,so i do this by reference the answer.namely,How to read/write a boolean when implementing the Parcelable interface?

But something wrong happens, I got a null reference error. It says:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference.

Codes is as follows.

public class User implements Parcelable{
    private String userName;
    private String passWord;
    private Boolean oldUser;

    public String getUserName() {
        return userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public Boolean getOldUser() {
        return oldUser;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public void setOldUser(Boolean oldUser) {
        this.oldUser = oldUser;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        User user = new User();
        parcel.writeString(user.userName);
        parcel.writeString(user.passWord);
        //seems a good way by using the official api.
        //parcel.writeBooleanArray(new boolean[]{user.oldUser});
        //null pointer,why?
        parcel.writeByte((byte) (user.oldUser ? 1 : 0));
    }

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        public User createFromParcel(Parcel in) {
            User user = new User();
            //boolean[] myBooleanArr = new boolean[1];
            user.userName = in.readString();
            user.passWord = in.readString();
            //more codes needed to use the below api.
            //in.readBooleanArray(myBooleanArr);
            //user.oldUser = myBooleanArr[0];

            //method we define using readInt.
            user.oldUser = (in.readInt() != 0);
            return user;
        }

        public User[] newArray(int size) {

            return new User[size];
        }
    };
}

Log messages:

log messages

E/AndroidRuntime: FATAL EXCEPTION: main
              Process: com.example.thon.scos, PID: 2838
              java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.Boolean.booleanValue()' on a null object reference
                  at es.source.code.model.User$override.writeToParcel(User.java:52)
                  at es.source.code.model.User$override.access$dispatch(User.java)
                  at es.source.code.model.User.writeToParcel(User.java:0)
                  at android.os.Parcel.writeParcelable(Parcel.java:1416)
                  at android.os.Parcel.writeValue(Parcel.java:1322)
                  at android.os.Parcel.writeArrayMapInternal(Parcel.java:665)
                  at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1330)
                  at android.os.Bundle.writeToParcel(Bundle.java:1079)
                  at android.os.Parcel.writeBundle(Parcel.java:690)
                  at android.content.Intent.writeToParcel(Intent.java:7793)
                  at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2639)
                  at android.app.Instrumentation.execStartActivity(Instrumentation.java:1507)
                  at android.app.Activity.startActivityForResult(Activity.java:3917)
                  at android.app.Activity.startActivityForResult(Activity.java:3877)
                  at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:861)
                  at android.app.Activity.startActivity(Activity.java:4200)
                  at android.app.Activity.startActivity(Activity.java:4168)
                  at es.source.code.activity.LoginOrRegister$1.onClick(LoginOrRegister.java:46)
                  at android.view.View.performClick(View.java:5198)
                  at android.view.View$PerformClick.run(View.java:21147)
                  at android.os.Handler.handleCallback(Handler.java:739)
                  at android.os.Handler.dispatchMessage(Handler.java:95)
                  at android.os.Looper.loop(Looper.java:148)
                  at android.app.ActivityThread.main(ActivityThread.java:5417)
                  at java.lang.reflect.Method.invoke(Native Method)
                  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

honestly,I am a new guy both in android and java.I tried by editing

parcel.writeByte((byte) (user.oldUser ? 1 : 0));

to

parcel.writeByte((byte) (oldUser ? 1 : 0));

Amazing, it does works and all the errors are gone.

is the solution correct? I just can't figure out. What is the best way to handle this? Thanks.

like image 431
xjas Avatar asked Dec 19 '22 12:12

xjas


1 Answers

You should not create a new User object when writing the parcel. You are operating on the current object instance.

I guess you can perform all the logic for object creation and reading the parcel in the createFromParcel() method but I have seen the pattern below more often where you pass the parcel into a constructor for the object and handle it there. Make sure you read and write the fields to the parcel in the same exact order.

public class User implements Parcelable {

    private String userName;
    private String passWord;
    private boolean oldUser;

    public User(Parcel in) {
        userName = in.readString();
        passWord = in.readString();
        oldUser = in.readInt() == 1;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(userName);
        dest.writeString(passWord);
        dest.writeInt(oldUser ? 1 : 0);
    }

    public String getUserName() {
        return userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public boolean getOldUser() {
        return oldUser;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public void setOldUser(boolean oldUser) {
        this.oldUser = oldUser;
    }

    @Override
    public int describeContents() {
        return 0;
    }

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        public User createFromParcel(Parcel in) {
            return new User(in);
        }

        public User[] newArray(int size) {
            return new User[size];
        }
    };    

}
like image 177
Abtin Gramian Avatar answered May 08 '23 01:05

Abtin Gramian