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