Pergunta

É possível iniciar uma atividade na pilha, limpando todo o histórico anterior?

A situação

Eu tenho uma pilha de atividades que vai A-> B-> C ou B-> C (a tela A seleciona o token do usuário, mas muitos usuários possuem apenas um único token).

Na tela C o usuário poderia executam uma ação que torna a tela B inválida, então o aplicativo deseja levá-los para a tela A, independentemente de ela já estar na pilha.A tela A deve então ser o único item na pilha do meu aplicativo.

Notas

Existem muitas outras perguntas semelhantes, mas não encontrei nada que responda exatamente a essa pergunta.Eu tentei ligar getParent().finish() - isso sempre resulta em uma exceção de ponteiro nulo. FLAG_ACTIVITY_CLEAR_TOP só funciona se a atividade já estiver na pilha.

Foi útil?

Solução

No nível 11 da API, uma nova bandeira de intenção foi adicionada apenas para isso: INTENT.FLAG_ACTIVO_CLEAR_TASK

Apenas para esclarecer, use isto:

Java

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);


Kotlin

intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK


Infelizmente para a API lvl <= 10, ainda não encontrei uma solução limpa para isso. o Solução "Donthackandroidlikethis" é de fato puro hackery. Você não deveria fazer isso. :)

Editar:Conforme @Ben Pearsoncomentário, para API <= 10 agora se pode usar IntentCompat classe para o mesmo. Pode -se usar IntentCompat.FLAG_ACTIVITY_CLEAR_TASK sinalizador para limpar a tarefa. Assim, você também pode apoiar o nível 11 da API.

Outras dicas

Caso 1: Apenas duas atividades A e B:

Aqui, o fluxo de atividades é A-> b. Tela de aplicação de hospedagem/respingo.

Intent newIntent = new Intent(A.this, B.class);
startActivity(newIntent);
finish();

Caso 2: Mais de duas atividades:

Se houver um fluxo como A-> B-> C-> D-> B e ao clicar no botão de volta na atividade B enquanto vier da atividade D. Nesse caso, devemos usar.

Intent newIntent = new Intent(D.this,B.class);
newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 
newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(newIntent);

Aqui, a atividade B será iniciada na história de fundo, em vez de uma nova instância por causa de intenção.flag_activity_clear_top e intent.flag_activity_new_task limpa a pilha e o torna o top. Então, quando pressionarmos o botão de volta, todo o aplicativo será encerrado.

Com a versão mais recente do Android> = Uso da API 16 finishAffinity()

A abordagem é adequada para> = API 16.

Intent mIntent = new Intent(mContext,MainActivity.class);
finishAffinity();
startActivity(mIntent);
  • É o mesmo que iniciar uma nova atividade e limpar toda a pilha.
  • Ou reinicie a MainActivity/Firstativity.

Passei algumas horas também ... e concordo que Flag_Activity_Clear_top soa como o que você deseja: limpe toda a pilha, exceto a atividade que está sendo lançada, para que o botão traseiro sai do aplicativo. No entanto, como Mike Repass mencionou, Flag_Activity_Clear_top só funciona quando a atividade que você está lançando já está na pilha; Quando a atividade não está lá, a bandeira não faz nada.

O que fazer? Coloque a atividade sendo lançada na pilha com flag_activity_new_task, o que torna essa atividade o início de uma nova tarefa na pilha de histórico. Em seguida, adicione o sinalizador flag_activity_clear_top.

Agora, quando FLAG_ACTIVIDE_CLEAR_TOP vai encontrar a nova atividade na pilha, ela estará lá e será puxada antes que tudo seja limpo.

Aqui está minha função de logout; O parâmetro de exibição é o botão ao qual a função é anexada.

public void onLogoutClick(final View view) {
    Intent i = new Intent(this, Splash.class);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    startActivity(i);
    finish();
}

Você não deve mudar a pilha.O botão Voltar do Android deve funcionar como em um navegador da web.

Posso pensar em uma maneira de fazer isso, mas é um truque e tanto.

  • Faça suas atividades singleTask adicionando-o ao AndroidManifestExemplo:

    <activity android:name=".activities.A"
              android:label="@string/A_title"
              android:launchMode="singleTask"/>
    
    <activity android:name=".activities.B"
              android:label="@string/B_title"
              android:launchMode="singleTask"/>
    
  • Ampliar Application que manterá a lógica de para onde ir.

Exemplo:

public class DontHackAndroidLikeThis extends Application {

  private Stack<Activity> classes = new Stack<Activity>();

  public Activity getBackActivity() {
    return classes.pop();
  }

  public void addBackActivity(Activity activity) {
    classes.push(activity);
  }
}

De a para B:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(A.class); 
startActivity(this, B.class);

De B ​​a C:

DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
app.addBackActivity(B.class); 
startActivity(this, C.class);

Em C:

If ( shouldNotGoBackToB() ) {
  DontHackAndroidLikeThis app = (DontHackAndroidLikeThis) getApplication();
  app.pop();
}

e segure o botão Voltar para pop() da pilha.

Mais uma vez, você não deveria fazer isso :)

Imediatamente após iniciar uma nova atividade, usando startActivity, certifique -se de ligar finish() para que a atividade atual não esteja empilhada atrás da nova.

Experimente isso:

Intent logout_intent = new Intent(DashboardActivity.this, LoginActivity.class);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
logout_intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(logout_intent);
finish();
Intent i = new Intent(MainPoliticalLogin.this, MainActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(i);

Tente o código abaixo,

Intent intent = new Intent(ManageProfileActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|
                Intent.FLAG_ACTIVITY_CLEAR_TASK| 
                Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);

Para mim Nenhum dos métodos acima não funciona.

Apenas faça isso com limpe toda a atividade anterior:

finishAffinity() // if you are in fragment use activity.finishAffinity()
Intent intent = new Intent(this, DestActivity.class); // with all flags you want
startActivity(intent)

Eu achei um hack muito simples, basta fazer isso adicionar novo elemento em AndroidManifest Como:-

<activity android:name=".activityName"
          android:label="@string/app_name"
          android:noHistory="true"/>

a android:noHistory Limpará sua atividade indesejada da pilha.

Às vezes, seu emulador Android pode não conectar a ferramenta Eclipse DDMS e pedir que o ADB comece manualmente. Nesse caso, você pode iniciar ou interromper o ADB usando o prompt de comando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top