How to Use Parcel in Android

How to use Parcel in Android?

Ah, I finally found the problem. There were two in fact.

  1. CREATOR must be public, not protected. But more importantly,
  2. You must call setDataPosition(0) after unmarshalling your data.

Here is the revised, working code:

public void testFoo() {
final Foo orig = new Foo("blah blah");
final Parcel p1 = Parcel.obtain();
final Parcel p2 = Parcel.obtain();
final byte[] bytes;
final Foo result;

try {
p1.writeValue(orig);
bytes = p1.marshall();

// Check to make sure that the byte stream seems to contain a Parcelable
assertEquals(4, bytes[0]); // Parcel.VAL_PARCELABLE

p2.unmarshall(bytes, 0, bytes.length);
p2.setDataPosition(0);
result = (Foo) p2.readValue(Foo.class.getClassLoader());

} finally {
p1.recycle();
p2.recycle();
}

assertNotNull(result);
assertEquals( orig.str, result.str );

}

protected static class Foo implements Parcelable {
public static final Parcelable.Creator<Foo> CREATOR = new Parcelable.Creator<Foo>() {
public Foo createFromParcel(Parcel source) {
final Foo f = new Foo();
f.str = (String) source.readValue(Foo.class.getClassLoader());
return f;
}

public Foo[] newArray(int size) {
throw new UnsupportedOperationException();
}

};

public String str;

public Foo() {
}

public Foo( String s ) {
str = s;
}

public int describeContents() {
return 0;
}

public void writeToParcel(Parcel dest, int ignored) {
dest.writeValue(str);
}

}

How can I make my custom objects Parcelable?

You can find some examples of this here, here (code is taken here), and here.

You can create a POJO class for this, but you need to add some extra code to make it Parcelable. Have a look at the implementation.

public class Student implements Parcelable{
private String id;
private String name;
private String grade;

// Constructor
public Student(String id, String name, String grade){
this.id = id;
this.name = name;
this.grade = grade;
}
// Getter and setter methods
.........
.........

// Parcelling part
public Student(Parcel in){
String[] data = new String[3];

in.readStringArray(data);
// the order needs to be the same as in writeToParcel() method
this.id = data[0];
this.name = data[1];
this.grade = data[2];
}

@Оverride
public int describeContents(){
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {this.id,
this.name,
this.grade});
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public Student createFromParcel(Parcel in) {
return new Student(in);
}

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

Once you have created this class, you can easily pass objects of this class through the Intent like this, and recover this object in the target activity.

intent.putExtra("student", new Student("1","Mike","6"));

Here, the student is the key which you would require to unparcel the data from the bundle.

Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");

This example shows only String types. But, you can parcel any kind of data you want. Try it out.

EDIT: Another example, suggested by Rukmal Dias.

When to use parcelable in android?

As you already discovered if you want to send own data via Intent you need to make it possible. On Android it's recommended to use Parcelable. You may implement this interface yourself or use existing tools like Parceler or Parcelable Please. Note: these tools comes with some limitation so ensure you know them as sometimes it may be cheaper to implement Parcelable by hand instead of writing code to work it around.

is parcelable to only way possible

No. You can use Serializable (also with Parcels), but Parcelable is the way to go on Android as it is faster and it is how it's done on platform level.

What is Parcelable in android

This concept is called Parcelable

A Parcelable is the Android implementation of the Java Serializable. It assumes a certain structure and way of processing it. This way a Parcelable can be processed relatively fast, compared to the standard Java serialization.

To allow your custom object to be parsed to another component they need to implement the android.os.Parcelable interface. It must also provide a static final method called CREATOR which must implement the Parcelable.Creator interface.

The code you have written will be your model class.

You can use Parcelable in Activity like :

intent.putExtra("student", new Student("1")); //size which you are storing

And to get this object :

Bundle data = getIntent().getExtras();
Student student = (Student) data.getParcelable("student");

Here Student is a model class name. replace this with yours.

In simple terms Parcelable is used to send a whole object of a model class to another page.

In your code this is in the model and it is storing int value size to Parcelable object to send and retrieve in other activity.

Reference :

Tutorial 1

Tutorial 2

Tutorial 3

Is there a convenient way to create Parcelable data classes in Android with Kotlin?

Kotlin 1.1.4 is out

Android Extensions plugin now includes an automatic Parcelable implementation generator. Declare the serialized properties in a primary constructor and add a @Parcelize annotation, and writeToParcel()/createFromParcel() methods will be created automatically:

@Parcelize
class User(val firstName: String, val lastName: String) : Parcelable

So you need to enable them adding this to you module's build.gradle:

apply plugin: 'org.jetbrains.kotlin.android.extensions'

android {
androidExtensions {
experimental = true
}
}

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 use Parcelable in fragment for getting data?

Passing data to Fragments is carried by using Bundles but not Intents.

In FragmentSend change

Intent intent = new Intent(getContext(), FragmentGet.class);
intent.putExtra("Student", model);

Fragment fragmentGet = new FragmentGet();
fragmentGet.setArguments(intent.getExtras());

to this

Fragment fragmentGet = new FragmentGet();
Bundle bundle = new Bundle();
bundle.putParcelable("Student", model);
fragmentGet.setArguments(bundle);

And to receive the data in FragmentGet change

Bundle bundle = getActivity().getIntent().getExtras();
model = bundle.getParcelable("Student");

to

Bundle bundle = this.getArguments();
if (bundle != null) {
model = bundle.getParcelable("Student");
}

Android: How to pass Parcelable object to intent and use getParcelable method of bundle?

Intent provides bunch of overloading putExtra() methods.

Suppose you have a class Foo implements Parcelable properly, to put it into Intent in an Activity:

Intent intent = new Intent(getBaseContext(), NextActivity.class);
Foo foo = new Foo();
intent.putExtra("foo ", foo);
startActivity(intent);

To get it from intent in another activity:

Foo foo = getIntent().getExtras().getParcelable("foo");


Related Topics



Leave a reply



Submit