How to Read/Write a Boolean When Implementing the Parcelable Interface

How to read/write a boolean when implementing the Parcelable interface?

Here's how I'd do it...

writeToParcel:

dest.writeByte((byte) (myBoolean ? 1 : 0));     //if myBoolean == true, byte == 1

readFromParcel:

myBoolean = in.readByte() != 0;     //myBoolean == true if byte != 0

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

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];
}
};

}

How to store boolean property for Parcelable interface?

The ternary operator is not supported in kotlin
Use if-else instead

writeInt(if(isAdmin) 1 else 0)

Im using writeValue instead, it also usefull for nullable variables

dest.writeValue(this.booleanVar)
booleanVar = parcel.readValue(Boolean::class.java.classLoader) as? Boolean?

if it could be nullable and if not add ?: false

upd: as pointed in other answers dest variable cannot be null. afaik it marked as nullable after code converting using Android Studio. If you use that feature better to double check your code because of convertation could work not properly sometimes.

About ?. in general. You can rewrite it with let operator

dest?.let { it ->
it.write(....)

or even better

dest ?: retrun

How to implement the write & read in Parcelable Class

To write the card

out.writeParcelable(mCard, flags);

To read the card

mCard = (Card) in.readParcelable(Card.class.getClassLoader());

To write the Boolean

out.writeInt(mLifeStatus ? 1 : 0);
out.writeInt(mProtected ? 1 : 0);

To read the Boolean

mLifeStatus = in.readInt() == 1;
mProtected = in.readInt() == 1;

(This is how writeValue and readValue work internally for Boolean types)

How to use Parcel.readBooleanArray()?

I believe you need to pass a boolean[], the values in the Parcel will be copied to that, then you read from that array.

Sample code:

boolean[] myBooleanArr = new boolean[1];
parcel.readBooleanArray(myBooleanArr);
boolean value = myBooleanArr[0];

How to read ListListListDouble using Parcelable in Android

You may need to implement a specialize ArrayList that is Parcelable for this to work. How to implement Parcelable for a class containing List<List<String>>? The accepted answer here is good but you may want to use generics so it can used for more than just String or in your instance Double

As a side note you may want to look into a single layer solution for you coordinates something like this.

public class Coordinates implements Parcelable{
public double x;
public double y;
public double z;
// You get the gist
}
List<Coordinates> coordinates = new ArrayList<>();

If you can do this you could avoid the above problem altogether. Again I have no clue about your setup and I could be completely wrong BUT a nested nested List is not the prettiest thing in the world.

Explanation about Parcelable Interface

Is it a problem if the method writeToParcel() and the constructor private Media (Parcel parcel) menage 4 fields inside their body?

That should be fine.

How should I manage a Uri field? Is it correct the way I did it?

What you have should be fine. Personally, I would convert it to and from a string, just because I hate messing with classloaders.

I get a compile error even though Uri class implements Serializable.

Uri does not implement Serializable. It implements Parcelable. See the JavaDocs.

kotlin - how to make a nullable boolean within a Parceable

You can use .let{} to return the computed value.

constructor(parcel: Parcel) : this(parcel.readByte().let { if(it < 0) null else (it > 0) },parcel.readInt())

Read and Write Long Object in Android Parcelable Class

The problem with your approach is that a Long value may be null but the Parcel methods only take/ return values of the primitive data type long, see the documentation for details. So you need a workaround to store a Long value.

I like to use a int to indicate whether my Long value is null (you can only store boolean arrays no single boolean values) and a long to store the numerical value if it isn't:

Writing to the Parcel

int indicator = (aLongObject == null) ? 0 : 1;
long number = (aLongObject == null) ? 0 : aLongObject;
dest.writeInt(indicator);
dest.writeLong(number);

Reading from the Parcel

// NOTE: reading must be in the same order as writing
Long aLongObject;
int indicator = in.readInt();
long number = in.readLong();
if(indicator == 0){
aLongObject = null;
}
else{
aLongObject = number;
}


Related Topics



Leave a reply



Submit