Can android.graphics.Path be made Parcelable? - android

I've found a few topics about making Path a Serializable object but I couldn't find anything about making it Parcelable. From what I've read, Parcelable objects are more efficient for packing and unpacking in a Bundle.
I've made a new object called ParcelablePath, which extends 'Path' and implements Parcelable and have overridden the required methods, but I'm not really sure what to do in the overridden methods.
My question is, is it even possible to make Path a Parcelable object? If so how can I do it?
Here is some sample code:
public class ParcelablePath extends Path implements Parcelable {
protected ParcelablePath(Parcel in) {
}
public static final Creator<ParcelablePath> CREATOR = new Creator<ParcelablePath>() {
#Override
public ParcelablePath createFromParcel(Parcel in) {
return new ParcelablePath(in);
}
#Override
public ParcelablePath[] newArray(int size) {
return new ParcelablePath[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
}

If you are using Android Studio there's a nice plugin which will solve your issue and automate the process for making a class Parcelable.
You can have a look here: Quickly Create Parcelable Class in Android Studio
Android Tutorials Mobile Development

Related

Is it possible to create a Parcelable Class that has an empty constructor?

I'm trying to use firestore recycler adapter with a parcelable class, but it needs to have an empty constructor.
My solution now is to create a regular class with an empty constructor and right after fetching the data, I'll map the objects into a parcelable copy.
But is it possible to create a Parcelable Class with an empty constructor? In Android Studio when I do right click -> Generate -> I see no secondary constructor option so I guess it's not possible, right?
Yes, it is possible. The Parcelable object will be serialized and deserialized without any problem.
In Android Studio when I do right click -> Generate -> I see no secondary constructor option so I guess it's not possible, right?
No, the fact that it doesn't appear as suggestion in Android Studio code completion feature doesn't mean it is not possible.
Taking as a reference the Parcelable implementation from Android documentation. You should then need to add an empty constructor. Just write the code, don't use code generator.
public MyParcelable(){
}
The class then 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();
}
public MyParcelable(){
}
}

Should Parcel.writeSerializable be used in a Parcelable.writeToParcel?

I am new to android and am having a bit of trouble wrapping my head around the Parcelable interface.
I eventually found this:
https://stackoverflow.com/a/2141166/6647053
The point made in the above answer is that when passing an object to an activity, this:
intent.putExtra("object", parcelableObject);
performs much better than this:
intent.putExtra("object", serializableObject);
My question is:
Would there be any performance benefit to using a Parcel's read / write Serializable methods within the Parcelable (as opposed to just using a serializable object with intent.putExtra)? Why / Why not?
Example:
public class MyParcelable implements Serializable, Parcelable {
/* Some Custom Object Stuff Here */
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeSerializable(this);
}
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
public MyParcelable createFromParcel(Parcel parcel) {
return parcel.readSerializable();
}
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
There is no benefit to writing this: parceling will be as slow as serializing.
In ordinary Java, Externalizable can perform better than Serializable, because you supply your own readExternal(ObjectInput in) and writeObject(ObjectOutput out) in which you are expected to manually serialize your fields instead of relying on the JVM to introspect and automatically do it for you. Android's Parcelable serves a similar purpose.

Error with implementing Parcelable object

I'm kind of new to Android development.
I don't understand why the following code gives me a stackoverflowerror
Intent intent = new Intent(view.getContext(), MakeCall.class);
SipParcelable sipp = new SipParcelable(_sip);
intent.putExtra("sip", (Parcelable) sipp);
startActivity(intent);
Basically as soon as the startActivity(intent) fires, I get the following error:
I can get rid of the error by commenting out the third line with the putExtra() function.
I'm trying to pass my _sip object over to the MakeCall.class activity on another screen that's about to load up. I tried to follow the tutorial on how to implement a Parcelable class/object. Here's what my SipParcelable code looks like:
import com.myproject.library.SipService;
import android.os.Parcel;
import android.os.Parcelable;
public class SipParcelable implements Parcelable{
public SipService mData;
/* everything below here is for implementing Parcelable */
// 99.9% of the time you can just ignore this
public int describeContents() {
return 0;
}
// write your object's data to the passed-in Parcel
public void writeToParcel(Parcel out, int flags) {
out.writeValue(mData);
}
public SipParcelable(SipService sip)
{
mData = sip;
}
// Parcelling part
public SipParcelable(Parcel in){
mData = (SipService) in.readValue(SipService.class.getClassLoader());
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
public SipParcelable createFromParcel(Parcel in) {
return new SipParcelable(in);
}
public SipParcelable[] newArray(int size) {
return new SipParcelable[size];
}
};
}
What am I doing wrong?
Your SipService class must implement parcelabe and modify how SipService object is read and written from/to pracel.
check this tutorial it might help you
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
You can use serialisable too… But parcelable is faster and better
NOTE: all properties of an object (if the properties are objects) that implements parcelable, must also be parcelable as well.

How to share objects with other activities?

My program has a range of different class activities (basically different screens). In one activity I am creating multiple objects which I would then like to access in other activities.
How do I go about making these objects accessible to other activities within my program, in other words how do I share objects with other activities?
TIA
Mark
The first thing you need to resolve is the operation order. If activity A is the one with the shared objects, what would you do if activity B is run without activity A ever being initialized? Do remember that intents to start activities may come from everywhere, though, to be truthful, exiting with NULL pointer dereference is an acceptable response.
What I did when such a thing was necessary was to not have the shared objects part of the activity, but create a specific object for containing those. You can then store a static reference to that object inside the object, and return it via a static method:
public class GlobalParams {
private static reference;
public static GlobalParams getReference()
{
if( reference==NULL )
reference=new GlobalParams();
return reference;
}
}
I don't think parcelable would help you, as that would create distinct copies for the different Activities to use.
Shachar
You need to have that class implement Parcelable
It's basically kinda similar to Java's serializable. You have to tell your class how to pack and unpack itself. Then you can just put it in an intent via intent.putExtra();
Here is the code example taken from that link
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();
}
}

Extending a class that implements Parcelable

I have a class, we'll call it class A, that implements Parcelable.
I have a second class, we'll call it class B, that extends class A.
My question is:
How do I write class B's member variables to the Parcel and then write it's parent class's (ie: class A's) member variables to the Parcel (and, subsequently, read them in)?
Is there some nifty trick to not needing to rewrite class A's Parcel code? Or do I just need to rewrite the Parcel code in class A and add additional code for class B's member variables?
How do I write class B's member variables to the Parcel and then write it's parent class's (ie: class A's) member variables to the Parcel
Class B overrides writeToParcel() from Class A, chaining to the superclass and also adding its own objects to the Parcel.
(and, subsequently, read them in)?
Class B implements public static final Parcelable.Creator<MyParcelable> CREATOR in such a way that it can let both classes read their stuff in. If you take the approach of creating a constructor on Class B that takes a Parcel as a constructor parameter, just chain to the superclass constructor (to let Class A do its work), then read Class B's data.
The key will be to do them both in the same order. If you intend to let Class A read its data first, Class A must write its data first.
Is there some nifty trick to not needing to rewrite class A's Parcel code?
Inheritance and chaining to the superclass.
Adding an example, the marked answer is indeed correct, but something more visual seems more suitable for this situation:
This would be the supper class:
public class BasePojo implements Parcelable {
private String something;
//what ever other constructor
//getters and setters
protected BasePojo(Parcel in) {
something = in.readString();
}
public static final Creator<BasePojo> CREATOR = new Creator<BasePojo>() {
#Override
public BasePojo createFromParcel(Parcel in) {
return new BasePojo(in);
}
#Override
public BasePojo[] newArray(int size) {
return new BasePojo[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(something);
}
}
And then this would be the child class:
public class ChildPojo extends BasePojo implements Parcelable {
private int somethingElse;
//what ever other constructor
//getters and setters
protected ChildPojo(Parcel in) {
super(in);
somethingElse = in.readInt();
}
public static final Creator<ChildPojo> CREATOR = new Creator<ChildPojo>() {
#Override
public ChildPojo createFromParcel(Parcel in) {
return new ChildPojo(in);
}
#Override
public ChildPojo[] newArray(int size) {
return new ChildPojo[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
super.writeToParcel(parcel, i);
parcel.writeInt(somethingElse);
}
}
The marked answer provides a very good explanation, calling super is the key.
It is a little complex, but the trick is to use Reflection to get the types of subclass's members and to sort the members so that you can read and write the data back in the same exact order using the proper types.
I have implemented the solution for class A here: https://github.com/awadalaa/Android-Global-Parcelable
so now you can make any class parcelable by simply extending this class.

Categories

Resources