When my app goes into background I see onSavedInstanceState
is called and I try to save an instance of an object using Parcelable
. However, when my app returns to foreground, only onResume
is called, never onCreate
or onRestoreInstanceState
although I save data in onSavedInstanceState
. When I continue to use the app, the data is indeed lost and it crashes. Hence I need to make sure the state is recreated.
According to the documentation:
"The system calls onRestoreInstanceState() only if there is a saved state to restore, so you do not need to check whether the Bundle is null."
I see that onSavedInstanceState
is called by the printout -----Saving Session-----
.
The app crashes because some counters to positions in arrays are lost when entering pause
-mode. So that is not really a problem, just shows I need to restore that state of the Session
-instance.
EDIT: The app crashed due to a silly mistake by me. The data actually did not need to be saved. However, onSaveInstanceState
is called, but never onRestoreInstanceState
despite the documentation says so. I still do not understand that.
The life-cycle looks like:
OnPause
OnSaveInstanceState
OnStop
OnStart
OnResume
This is how I save the object:
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(SESSION_KEY, mSession);
System.out.println(" ----- Saving Session --------");
}
Restore:
@Override
protected void onRestoreInstanceState(Bundle bundle) {
System.out.println("OnRestoreInstanceState");
super.onRestoreInstanceState(bundle);
String tmp = bundle.getString("TEST_KEY");
System.out.println(tmp);
}
Implementing Parcelable
in Session
:
protected Session(Parcel in) {
mFinalists = in.readArrayList(Finalist.class.getClassLoader());
shootingOrder = in.readParcelable(ShootingOrder.class.getClassLoader());
nbrshots = in.readInt();
nextSession = in.readArrayList(Integer.class.getClassLoader());
remaining = in.readArrayList(Integer.class.getClassLoader());
eliminated = in.readArrayList(Integer.class.getClassLoader());
circleIndex = in.readArrayList(Integer.class.getClassLoader());
mOldStations = in.readArrayList(OldStations.class.getClassLoader());
}
public static final Creator<Session> CREATOR = new Creator<Session>() {
@Override
public Session createFromParcel(Parcel in) {
System.out.println("Restoring Session");
return new Session(in);
}
@Override
public Session[] newArray(int size) {
return new Session[size];
}
};
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeList(mFinalists);
dest.writeParcelable(shootingOrder, flags);
dest.writeInt(nbrshots);
dest.writeList(nextSession);
dest.writeList(remaining);
dest.writeList(eliminated);
dest.writeList(circleIndex);
dest.writeList(mOldStations);
dest.writeList(mCurrentStation);
dest.writeList(mCurrentColors);
boolean tmp[] = {isShootOff, isInitilized};
dest.writeBooleanArray(tmp);
dest.writeInt(sOffShots);
}
I also implement Finalist
, ShootingOrder
and OldStation
as Parcelable
:
protected Finalist(Parcel in) {
int tmp[] = new int[100];
in.readIntArray(tmp);
mName = in.readString();
mPosition = in.readInt();
int resultSize = in.readInt();
result = new ArrayList<>();
for (int i = 0; i < resultSize; i++){
result.add(tmp[i]);
}
System.out.println("Restoring Finalist");
}
public static final Creator<Finalist> CREATOR = new Creator<Finalist>() {
@Override
public Finalist createFromParcel(Parcel in) {
return new Finalist(in);
}
@Override
public Finalist[] newArray(int size) {
return new Finalist[size];
}
};
private int[] getResultArray(){
int tmp[] = new int[result.size()];
for (int i = 0; i < result.size(); i++){
tmp[i] = result.get(i);
}
return tmp;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
int tmp[] = getResultArray();
dest.writeIntArray(tmp);
dest.writeString(mName);
dest.writeInt(mPosition);
dest.writeInt(result.size());
}