Как лучше всего управлять / восстанавливать бэкстек приложения между несколькими сеансами?
Пример рабочего процесса:
- Активность A запущена (стек: A)
- Активность B запущена (стек: A B)
- Активность C запущена (стек: A B C)
- ...
- Пользователь какое-то время использует другое приложение (скажем, приложение GMail)
- ...
- Пользователь возвращается к моему приложению, но Android очищает задний стек.
На шаге 7 я хотел бы возобновить действие C, и если пользователь нажмет кнопку «Назад» 2 раза, он вернется к действию B, а затем к действию A.
[Изменить] Добавление деталей.
После шага 7 выше, по умолчанию в Android происходит следующее:
- Активность A запущена (стек: пуст, добавлен C)
И я хотел бы, чтобы пользователь чувствовал, что он все еще использует тот же сеанс:
- Действие C возобновлено (стек: A B C)
- Пользователь нажимает кнопку «Назад», действие B возобновляется (стек: A B)
- Пользователь нажимает кнопку «Назад», действие A возобновляется (стек: A)
Что было бы хорошим подходом к этой ситуации, избегая утечек памяти?
[Второе EDIT] Я разрабатывал обходной путь, используя общий класс UIController для всех действий и LauncherActivity для делегирования логики UIController.
Поскольку мне нужно перестроить задний стек только при запуске ActivityC, это решение работает нормально:
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
}
Если у кого-то есть лучшее решение, не стесняйтесь публиковать его.