How to save an instance of a custom class in onSaveInstanceState?
Custom objects can be saved inside a Bundle when they implement the interface Parcelable
.
Then they can be saved via:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable("key", myObject);
}
Basically the following methods must be implemented in the class file:
public class MyParcelable implements Parcelable {
private int mData;
public int describeContents() {
return 0;
}
/** save object in parcel */
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];
}
};
/** recreate object from parcel */
private MyParcelable(Parcel in) {
mData = in.readInt();
}
}
Check this answer.
Basically you have to save it inside a Bundle
.
I know "that this case is cold", but because i found this thread first, when I was searching for exactly the same thing (and found an answer by now):
Imagine Bundle as an XML file.
If you create a new <BUNDLE name="InstanceName" type="ClassName">
you can freely add elements and attributes in a fresh and empty namespace.
When onSaveInstance(Bundle outState)
of your MainActivity is called (you can also force this in onPause
), you can create a new: Bundle b = new Bundle();
Then call your (probably not inherited and not overriden) custom Method onSaveInstance(Bundle b)
in your own class with your newly created Bundle b.
Then (in onSaveInstance(Bundle outState)
) of your MainActivity, call outState.putBundle("StringClassAndInstanceName", b);
When you find this string in onCreate, you can either use a switch/case to recreate this object or (better) have a factory function in your custom class to work with Bundle and "StringClassAndInstanceName".
Kotlin Solution:
For custom class save in onSaveInstanceState
you can be converted your class to JSON
string and restore it with Gson
convertion. The following example is for Fragment
and Activity
:
For Activity:
For put class in saveInstanceState
:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val gson = Gson()
val json = gson.toJson(your_custom_class)
outState.putString("CUSTOM_CLASS", json)
}
Restore class:
override fun onRestoreInstanceState(savedInstanceState: Bundle) {
super.onRestoreInstanceState(savedInstanceState)
val json = savedInstanceState?.getString("CUSTOM_CLASS")
if (!json!!.isEmpty()) {
val gson = Gson()
testBundle = gson.fromJson(json, Session::class.java)
}
}
You can restore it on Activity onCreate
also.
For fragment:
For put class in saveInstanceState
:
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
val gson = Gson()
val json = gson.toJson(customClass)
outState.putString("CUSTOM_CLASS", json)
}
Restore class:
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
if (savedInstanceState != null) {
val json = savedInstanceState.getString("CUSTOM_CLASS")
if (!json!!.isEmpty()) {
val gson = Gson()
val customClass: CustomClass = gson.fromJson(json, CustomClass::class.java)
}
}
}