Restaure o Android back stack após o aplicativo ter sido fechado

9

Qual é a melhor prática para gerenciar / restaurar a pilha de backup do aplicativo entre várias sessões?

Exemplo de um fluxo de trabalho:

  1. Atividade A iniciada (pilha: A)
  2. Atividade B iniciada (pilha: A B)
  3. Atividade C iniciada (pilha: A B C)
  4. ...
  5. O usuário usa um aplicativo diferente (digamos o aplicativo do Gmail) por um tempo
  6. ...
  7. O usuário volta ao meu aplicativo, mas a pilha de trás foi removida pelo Android.

No passo 7, gostaria de ter a Atividade C retomada e que, se o usuário pressionar o botão Voltar 2 vezes, ele retornará para a Atividade B e, em seguida, para a Atividade A.

[Editar] Adicionando detalhes.

Após o passo 7 acima, o que acontece por predefinição no Android é este:

  1. Atividade A iniciada (pilha: vazia e C é adicionada)

Eu gostaria que o usuário sentisse que ele ainda está usando a mesma sessão:

  1. Atividade C retomada (pilha: A B C)
  2. O usuário pressiona o botão Voltar, a Atividade B é retomada (pilha: A B)
  3. O usuário pressiona o botão Voltar, a atividade A foi retomada (pilha: A)

Qual seria uma boa abordagem para esta situação, evitando vazamentos de memória?

[segundo EDIT] Eu venho elaborando uma solução alternativa usando um UIController de classe commong para todas as atividades e um LauncherActivity para delegar a lógica para o UIController.

Como eu só preciso reconstruir a pilha traseira quando o ActivityC foi iniciado, esta solução parece funcionar bem:

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
}

Se alguém tiver uma solução melhor, sinta-se à vontade para postá-la.

    
por David 26.07.2011 в 22:32
fonte

1 resposta

5

Parece que você deve definir isso como verdadeiro e permitir que o Android gerencie o gerenciamento da pilha de atividades.

android: alwaysRetainTaskState

  

Se esse atributo estiver definido como "true" na atividade raiz de uma tarefa, o comportamento padrão que acabamos de descrever não acontecerá. A tarefa retém todas as atividades em sua pilha mesmo após um longo período.

    
por CrackerJack9 04.08.2011 / 15:37
fonte