How can I save activity state (B) when moving to previous activity (A) and how to restore it's previous state when moving back (to activity B)?
SCENARIO
Content of activity B can be changed by user. After finishing work, performed changes can be persisted (e. g. saved to local DB). Before persisting, user may want to navigate back to previous activity. At this point, "work session" should be somehow saved temporary in memory. After returning back to activity B "work session" should be restored, so user can continue in work.
APPROACHES
Standard methods onCreate(Bundle)
and onSaveInstanceState(Bundle)
are used to restore/save activity state when device configuration changes (e. g. on rotate). As onSaveInstanceState(Bundle) is not part of activity's life-cycle, this method does not get called on "back-press" when activity is destroyed (by default finish()
is called). The same applies for onRestoreInstanceState(Bundle). Obviously these methods alone are not sufficient to restore activity state after lefting an activity.
Transfering bundle state between activities
One way I can think of is to override onBackPressed()
in such way it will start an Intent
to previous activity A with bundle state Intent#putExtras(Bundle)
of current activity B. When moving back, starting an Intent
to activity B, this bundle state will be delivered back Intent#putExtras(Bundle)
to restore the state of activity B. However this also require to override onCreate(Bundle)
and onSaveInstanceState(Bundle)
in A so bundle state of B would not be lost on configuration change before navigating back to B.
Not finishing an activity on back-press + non-default launchMode
Another way (more cleaner) is to override onBackPressed()
so that it would start Intent
to previous activity A without calling finish()
of current activity B so activity B will hang in memory in paused state (waiting for resume). To resume activity B, manifest configuration android:launchMode="singleInstance"
is required so android will use existing activity (paused B) instead of creating new one (B2) when navigating back to activity B (startIntent(B.class)
).
Details: launchMode singleInstance creates singleton activity in new task (task = set of activities with the same group id i. e. affinity, normally app activities have the same affinity i. e. app = single task).
Drawback: transition animations does not work with singleInstance mode. It seems that singleInstance task may not be fully initialized at animation time. For more details: Custom animation doesnt work on SingleInstance Activity.
Saving activity state to SharedPreferences
Saving activity state to SharedPreferences
on "back-press", restoring activity state from preferences in onCreate(Bundle)
like in following link Save activity state to SharedPreferences.
Drawback: unable to save Bundle
state (only primitives: putInt
, putString
, ...).
Others
Some of the methods listed in Share data between activities can be used. Answers from this link refers to developer.android.com/guide/appendix/faq/framework.html which is unfortunately broken. Here is an alternative source http://wing-linux.sourceforge.net/guide/appendix/faq/framework.html.
About sharing data via Application object:
- Don't Store Data in the
Application
Object, - Using the Android Application class to temporary persist data.
Based on Application class documentation, using static singletons over
Application
is more preferable.Base class for maintaining global application state. ...
Note: There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way. If your singleton needs a global context (for example to register broadcast receivers), include Context.getApplicationContext() as a Context argument when invoking your singleton's getInstance() method.
It seems that putting data in Application
object or static singleton is so far the best solution for this problem.
QUESTION
Is there any build-in solution for this (without need of overriding onBackPressed()
)? For example saving activity on back-stack with it's state. If not, what is the common pattern to save activity state in such situation?
RELATED POSTS (just to link them with this post)