explain what meaning of Parcelable.creator?
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
Parcelable objects allow you to serialise and deserialise on activity or fragment stop / start and it is Faster than Java serialisable.
The static CREATOR class creates your object from a Parcel via the createFromParcel method that takes in a parcel and passes it to a constructor in your class that does the grunt work.
The newArray method allows an array of your objects to be parcelled. Answer
And here is a good example of it Link
Parcelable.Creator creates instances of your MyParcelable from a Parcel object. For example the typic Parcelable should look like this :
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel out, int flags) {
out.writeInt(mData);
}
public static final Parcelable.Creator<MyParcelable> CREATOR
= new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
For more information you should check the official documentation :
Parcelable.Creator
Parcelable
Related
I have browsed the question on Stack and I found no question facing the particular problem. I have a class with two arraylist of custom objects. I am not sure how to implement writeToParcel for the parent class now. One option I found were readTypedList constructor, but I cant implement it twice. There is no readTypedListArray constructor that I can create an array ans send it.
Just a reminder the object are ArrayList and there are two such objects in the parent class. The github link for reference is here.
https://github.com/legalimpurity/PopularMoviesStage2/tree/master/app/src/main/java/popularmoviesstage1/legalimpurity/com/popularmoviesstage2/objects
You can add customArray using following way :
In MovieObject class:
#Expose
private ArrayList< ReviewObject > ReviewObjs = new ArrayList< ReviewObject >();
private ArrayList< TrailerVideoObject > TrailerVideoObjs = new ArrayList< TrailerVideoObject >();
writeToParcel() :
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(ReviewObjs);
dest.writeTypedList(TrailerVideoObjs);
}
and readFromParcel() :
private void readFromParcel(Parcel in) {
ReviewObjs = new ArrayList<ReviewObject>();
in.readTypedList(ReviewObjs, ReviewObject.CREATOR);
TrailerVideoObjs = new ArrayList<TrailerVideoObject>();
in.readTypedList(TrailerVideoObjs, TrailerVideoObject.CREATOR);
}
And add following lines in CustomClasses :
for ReviewObject :
public class ReviewObject implements Parcelable {
public static final Creator<ReviewObject> CREATOR = new Creator<ReviewObject>() {
public ReviewObject createFromParcel(Parcel in) {
return new ReviewObject(in);
}
public ReviewObject[] newArray(int size) {
return new ReviewObject[size];
}
};
// add other objects...
}
for TrailerVideoObject :
public class TrailerVideoObject implements Parcelable {
public static final Creator<TrailerVideoObject> CREATOR = new Creator<TrailerVideoObject() {
public TrailerVideoObject createFromParcel(Parcel in) {
return new TrailerVideoObject(in);
}
public TrailerVideoObject[] newArray(int size) {
return new TrailerVideoObject[size];
}
};
// add other objects...
}
You can try below workaround in MovieObject.java
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringArray(new String[] {
this.OrignalTitle,
this.MoviePosterImageThumbnailUrl,
this.PlotSynopsis,
this.UserRating,
this.ReleaseDate
});
dest.writeLongArray(new long[] {
this._id,
this.ApiId
});
ArrayList<ArrayList> temp = new List<>();
temp.add(ReviewObjs);
temp.add(TrailerVideoObjs);
dest.writeTypedList(temp);
}
In your MovieObject.java, you can declare them as List<YOUR_CLASS> instead of ArrayList<YOUR_CLASS>.
In my code:
public class CombinedClass implements Parcelable {
private List<Class1> class1List;
private List<Class2> class2List;
//Constructor, getter, setter, methods.
}
Both Class1 and Class2 implements Parcelable too.
I'm using "auto-generated" Parcelable implementation provided by Android Studio.
Here is the Parcelable implementation:
protected CombinedClass(Parcel in) {
class1List = in.createTypedArrayList(Class1.CREATOR);
class2List = in.createTypedArrayList(Class2.CREATOR);
}
public static final Creator<CombinedClass> CREATOR = new Creator<CombinedClass>() {
#Override
public CombinedClass createFromParcel(Parcel in) {
return new CombinedClass(in);
}
#Override
public CombinedClass[] newArray(int size) {
return new CombinedClass[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeTypedList(class1List);
parcel.writeTypedList(class2List);
}
I've a custom parcelable (simplified) that contains a string array:
public class MyClass implements Parcelable {
public static final Creator<MyClass> CREATOR = new Creator<MyClass>() {
public MyClass createFromParcel(Parcel in) {
return new MyClass(in);
}
public MyClass[] newArray(int size) {
return new MyClass[size];
}
};
#SerializedName(“tips”)
private List<String> Tips;
public MyClass() {
Tips = new ArrayList<>();
}
protected Category(Parcel in) {
Tips = in.createStringArrayList();
}
public List<String> getTips() {
return Tips;
}
public int describeContents() {
return 0;
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeStringList(Tips);
}
}
I'm trying to pass this parcelable via Intent to another activity. The process is VERY slow and sometimes I get an OOM exception...I don't understand why, I just want to pass a string array...
Save your array into database and pass id of that record.
I have a class A with and inner class B. like the code bellow. I dont know where I am going wrong. What would be the proper way to make Class A Parcelable? Here is how i have right now and its no good. Thanks!
public class A implements Parcelable
{
private B[][] bArray;
public A(Parcel in)
{
bArray = (B[][]) in.readSerializable();
}
#Override
public void writeToParcel(Parcel parcel, int i)
{
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public A createFromParcel(Parcel in) {
return new A (in);
}
public A[] newArray(int size) {
return new A[size];
}
};
static class B implements Parcelable
{
public B(Parcel in)
{
}
#Override
public void writeToParcel(Parcel parcel, int i)
{
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public B createFromParcel(Parcel in) {
return new B(in);
}
public B[] newArray(int size) {
return new B[size];
}
};
}
}
I created my own Parcelable class based on a snippet to send custom data via an Intent. Using it, Android (Min. API 10) gives me an exception, what it wrong with that piece of code below? I broke it down to a minimum. Here it is:
public class MyParcelable implements Parcelable {
private float[] data = null;
public MyParcelable(float[] data) {
this.data = data;
}
public MyParcelable(Parcel in) {
/* After this line the exception is thrown */
in.readFloatArray(data);
}
public static final Creator<MyParcelable> CREATOR = new Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
public int describeContents() {
return this.hashCode();
}
public void writeToParcel(Parcel out, int flags) {
out.writeFloatArray(data);
}
public float[] getData() {
return data;
}
}
After searching for a solution quite a while I stumbled upon this post where LionKing gave a working hint.
The Parcelable class now looks like this:
public class MyParcelable implements Parcelable {
private float[] data = null;
public MyParcelable(float[] data) {
this.data = data;
}
public MyParcelable(Parcel in) {
/* The exception is gone */
data = in.createFloatArray();
}
public static final Creator<MyParcelable> CREATOR = new Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
public int describeContents() {
return this.hashCode();
}
public void writeToParcel(Parcel out, int flags) {
out.writeFloatArray(data);
}
public float[] getData() {
return data;
}
}
This solution works also with the other base type arrays.
I have a class that contains data i want to pass it between intents, this class have arraylist that contains another class objects. this is my class
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long driveFreeSpaceSize;
ArrayList<Item>Items = new ArrayList<Item>();
}
class Item {
public String name;
public float percentage;
public int files;
public long size;
}
how can i send this class between intents ?
you can let your class Item implements the Serializable interface, and use Intent.putExtra(String, Serializable). Since ArrayList implements also the Serializable interface, you can pass the whole Items object.
This may be your problem:
Classes implementing the Parcelable interface must also have a static field called CREATOR, which is an object implementing the Parcelable.Creator interface.
Alternatively, I'd try to have Item implement Parcelable, as well.
The fail-safe alternative is to write your data structure into a JSON string, which also allows you to pass the data to other applications that don't have access to your ParsedData class.
You may take a look at Intent.putExtra(String name, Parcelable object) and implement the parcelable interface in your class.
i have found the answer after all. thanks all how helped me
this is the answer:
import android.os.Parcel;
import android.os.Parcelable;
public class ParsedData implements Parcelable {
public String error;
public float protectionLevel;
public int protectionLevelColor;
public double lastBackup;
public boolean compressedType;
public Long statusSendTime;
ArrayList<Item>Items = new ArrayList<Item>();
//---------------------Constructors---------------------------
public ParsedData() { ; };
public ParsedData(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(error);
dest.writeFloat(protectionLevel);
dest.writeInt(protectionLevelColor);
dest.writeDouble(lastBackup);
dest.writeByte((byte) (compressedType ? 1 : 0));
dest.writeLong(statusSendTime);
dest.writeList(Items);
}
private void readFromParcel(Parcel in) {
error = in.readString();
protectionLevel = in.readFloat();
protectionLevelColor = in.readInt();
lastBackup = in.readDouble();
compressedType =in.readByte() == 1;
statusSendTime = in.readLong();
in.readList(Items,Item.class.getClassLoader() );
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public ParsedData createFromParcel(Parcel in) {
return new ParsedData(in);
}
public ParsedData[] newArray(int size) {
return new ParsedData[size];
}
};
}
class Item implements Parcelable {
public String name;
public float percentage;
//---------------------Constructors---------------------------
public Item() {
}
public Item(Parcel in) {
readFromParcel(in);
}
//------------------------------------------------------------
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeFloat(percentage);
}
public static final Creator<Item> CREATOR = new Creator<Item>() {
public Item createFromParcel(Parcel source) {
return new Item(source);
}
public Item[] newArray(int size) {
return new Item[size];
}
};
private void readFromParcel(Parcel in) {
this.name = in.readString();
this.percentage = in.readFloat();
}
}
and in the caller activity
ParsedData data = new PArsedData();
Intent intentBreakDown = new Intent(this,BreakDownBarActivity.class);
intentBreakDown.putExtra("data", data);
startActivity(intentBreakDown);
in the called activity(BreakDownBarActivity in my case)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.breakdownbar);
Bundle b = getIntent().getExtras();
ParsedData data = (ParsedData)b.getParcelable("data");
}