Passing Serializable data with Intents :
https://www.udemy.com/the-ultimate-android-tutorial/learn/v4/t/lecture/1470686
class MyData implements Serializable {
String name;
String city;
String email:
}
Then I create an object for this class :
MyData mm = new MyData();
mm.name = name.getText().toString();
mm.city = city.getText().toString();
mm.email = email.getText().toString();
To send this object through an Intent :
Bundle b = new Bundle();
b.putSerializable(“myobject”, mm);
i.putExtras(b);
In other activity, how to use this object ??
Intent ii = getIntent();
Bundle bb = ii.getExtras();
MyData mObj = (MyData)bb.getSerializable(“myobject”);
then we can get all the information from this object.
Differences between Serialization and Parcelable
Parcelable and Serialization are used for marshaling and unmarshaling Java objects. Differences between the two are often cited around implementation techniques and performance results. From my experience, I have come to identify the following differences in both the approaches:
· Parcelable is well documented in the Android SDK; serialization on the other hand is available in Java. It is for this very reason that Android developers prefer Parcelable over the Serialization technique.
· In Parcelable, developers write custom code for marshaling and unmarshaling so it creates less garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves (around two times faster), because of this custom implementation.
· Serialization is a marker interface, which implies the user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java objects member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.
Passing Parcelable data with Intents :
https://guides.codepath.com/android/using-parcelable#overview
Parcelable — much lighter and much faster as compared to Serializable.
To allow for your class instances to be sent as a Parcel you must implement the Parcelable
interface along with a static field called CREATOR
, which itself requires a special constructor, private constructor, in your class.
Step 1 : Class needs to implement Parcelable
class MyData implements Parcelable {
String name;
String city;
int zipcode;
public MyData() {
// Normal actions performed by class, since this is still a normal object!
}
// Step 2 : Implement the methods from the Parcelable interface
@Override
public int describeContents() {
}
// this is the method of importance, here the contents are written to the Parcel
@Override
public void writeToParcel(Parcel dest, int flags) {
}
}
Typically, we don’t do anything in describeContents() method. This is mostly used internally.
Inside, writeToParcel() method we write data to the Parcel. This is how we write :
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeString(city);
dest.writeInt(zipcode);
}
Step 3: Recover data from Parcelable class
After implementing the ‘Parcelable’ interface methods, we need to create the ‘Parcelable.Creator<T> CREATOR’ constant for our class.
In order to recover data from Parcelable, we need to write another inner class like this :
// After implementing the `Parcelable` interface, we need to create the
// `Parcelable.Creator<T> CREATOR` constant for our class;
// Notice how it has our class specified as its type.
public static final Parcelable.Creator<MyData> CREATOR = new Parcelable.Creator<MyData>() {
// This simply calls our new constructor (typically private) and
// passes along the unmarshalled `Parcel`, and then returns the new object!
@Override
public MyData createFromParcel(Parcel in) {
return new MyData(in);
}
// We just need to copy this and change the type to match our class.
@Override
public MyData[] newArray(int size) {
return new MyData[size];
}
};
Now, to create an object from Parcel, we need to write a parameterized constructor in our class.
// Using the `in` variable, we can retrieve the values that
// we originally wrote into the `Parcel`. This constructor is usually
// private so that only the `CREATOR` field can access.
private MyParcelable(Parcel in) {
mData = in.readInt();
mName = in.readString();
mInfo = in.readParcelable(MySubParcelable.class.getClassLoader());
}
Note that the Parcelable
interface has two methods defined: int describeContents()
and void writeToParcel(Parcel dest, int flags)
. After implementing the Parcelable
interface, we need to create the Parcelable.Creator<MyParcelable> CREATOR
constant for our class which requires us to define createFromParcel
, newArray
.
Fully written Example :
public class MyParcelable implements Parcelable {
// You can include parcel data types
String mName;
String mCity;
int mZipcode;
// This is where you write the values you want to save to the `Parcel`.
// The `Parcel` class has methods defined to help you save all of your values.
// Note that there are only methods defined for simple values, lists, and other Parcelable objects.
// You may need to make several classes Parcelable to send the data you want.
@Override
public void writeToParcel(Parcel out, int flags) {
out.writeString(mName);
out.writeString(mCity);
out.writeInt(mZipcode);
}
// Using the `in` variable, we can retrieve the values that
// we originally wrote into the `Parcel`. This constructor is usually
// private so that only the `CREATOR` field can access.
private MyParcelable(Parcel in) {
mName = in.readString();
mCity = in.readString();
mZipcode = in.readInt();
}
public MyParcelable(String name, String city, int zipCode) {
mName = name;
mCity = city;
mZipcode = zipCode;
}
public MyParcelable() {
// Normal actions performed by class, since this is still a normal object!
}
// In the vast majority of cases you can simply return 0 for this.
// There are cases where you need to use the constant `CONTENTS_FILE_DESCRIPTOR`
// But this is out of scope of this tutorial
@Override
public int describeContents() {
return 0;
}
// After implementing the `Parcelable` interface, we need to create the
// `Parcelable.Creator<MyParcelable> CREATOR` constant for our class;
// Notice how it has our class specified as its type.
public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
// This simply calls our new constructor (typically private) and
// passes along the unmarshalled `Parcel`, and then returns the new object!
@Override
public MyParcelable createFromParcel(Parcel in) {
return new MyParcelable(in);
}
// We just need to copy this and change the type to match our class.
@Override
public MyParcelable[] newArray(int size) {
return new MyParcelable[size];
}
};
}
Passing Data Between Intents
We can now pass the parcelable data between activities within an intent:
// somewhere inside an Activity
MyParcelable dataToSend = new MyParcelable(name.getText().toString(), city.getText().toString(), Integer.parseInt(zipcode.getText().toString()));
Bundle b = new Bundle();
b.putParcelable("myobject", dataToSend);
Intent i = new Intent(this, NewActivity.class);
i.putExtras(b);
// i.putExtra("myData", dataToSend); // using the (String name, Parcelable value) overload!
startActivity(i); // dataToSend is now passed to the new Activity
and then access the data in the NewActivity using:
public class NewActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
Intent ii = getIntent();
Bundle bb = ii.getExtras();
MyParcelable object = (MyParcelable)bb.getParcelable("myobject");
// MyParcelable object = (MyParcelable) getIntent().getParcelableExtra("myData");
}
}
Now we can access the parcelable data from within the launched activity.