What's the best practise to manage / restore application back stack between multiple sessions ?
Exemple of a Workflow :
At step 7, I'd like to have Activity C resumed, and that if user presses the back button 2 times, it will go back to Activity B, and then Activity A.
[Edit] Adding details.
After step 7 above, What happens by default in Android is this :
And I would like the user to feel like he is still using the same session:
What would be a good approach to this situation while avoiding memory leaks ?
[Second EDIT] I have been crafting a workaround using a commong class UIController to all activities, and a LauncherActivity to delegate the logic to the UIController.
Since I only need to rebuild the back stack when ActivityC has been started, this solution seems to work fine :
public class UIController
{
private boolean _launched = false;
static private final UIController __instance = new UIController();
static public UIController getInstance() { return __instance; }
// Enforces the Singleton Pattern by preventing external access to constructor
private UIController() { }
public void onActivityCreated(Activity activity) {
if (!_launched)
{
if ( shouldRebuildStack() )
{
// Rebuild Activity stack
// Npte : actually Android will add ActivityA and ActivityB to the stack
// but will *NOT* create them right away. Only ActivityC will be
// created and resumed.
// Since they are in the back stack, the other activities will be
// created by Android once needed.
startActivity(activity, ActivityA.class);
startActivity(activity, ActivityB.class);
startActivity(activity, ActivityC.class);
} else {
// Starts default activity
startActivity(activity, ActivityA.class);
}
_launched = true;
}
}
public void onActivityResumed(Activity activity) {
memorizeCurrentActivity( activity.getClass().toString() );
}
private void memorizeCurrentActivity( String className ) {
// write className to preferences, disk, etc.
}
private boolean shouldRebuildStack() {
String previousActivity = " [load info from file, preferences, etc.] ";
return (previousActivity != null && previousActivity.equals("my.package.ActivityC"));
}
private void startActivity(Activity caller, Class newActivityClass)
{
Intent intent = new Intent(caller, newActivityClass);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
caller.startActivity( intent );
}
}
// This is the default activity in the AndroidManifest.xml
// This prevents ActivityA from starting right away if the UIController
// wants to rebuild the stack.
public class LauncherActivity() {
protected void onCreate(Bundle data) {
super.onCreate(data);
UIController.getInstance().onActivityCreated(this);
finish();
}
}
public class ActivityA() {
protected void onCreate(Bundle data) {
super.onCreate(data);
UIController.getInstance().onActivityCreated(this);
}
protected void onResume() {
super.onResume();
UIController.getInstance().onActivityResumed(this);
}
}
public class ActivityB() {
// onCreate() & onResume(), same as ActivityA
}
public class ActivityC() {
// onCreate() & onResume(), same as ActivityA
}
public class LauncherActivity() {
protected void onCreate(Bundle data) {
super.onCreate(data);
UIController.getInstance().onActivityCreated(this);
finish();
}
}
public class ActivityA() {
protected void onCreate(Bundle data) {
super.onCreate(data);
UIController.getInstance().onActivityCreated(this);
}
protected void onResume() {
super.onResume();
UIController.getInstance().onActivityResumed(this);
}
}
public class ActivityB() {
// same as ActivityA
}
public class ActivityC() {
// same as ActivityA
}
If someone has a better solution, feel free to post it.
Sounds like you should set this to true and let Android handle managing the activity stack.
If this attribute is set to "true" in the root activity of a task, the default behavior just described does not happen. The task retains all activities in its stack even after a long period.