Terminar uma atividade de outra atividade

101

Quero terminar uma atividade de outra atividade, como:

Na Atividade [A], ao clicar no botão, estou chamando a Atividade [B] sem terminar a Atividade [A].

Agora, na Atividade [B], existem dois botões, Novo e Modificar . Quando o usuário clica em modificar, pop uma atividade [A] da pilha com todas as opções marcadas.

Mas quando o usuário clicar no botão Novo da Atividade [B], terei que terminar a Atividade [A] da pilha e recarregar essa Atividade [A] novamente na pilha.

Estou tentando, mas não consigo terminar a Atividade [A] da pilha ... Como posso fazer isso?

Estou usando o código como:

Da Atividade [A]:

Intent GotoB = new Intent(A.this,B.class);
startActivityForResult(GotoB,1);

Outro método na mesma atividade

public void onActivityResult(int requestCode, int resultCode, Intent intent) {

    if (requestCode == 1)
    {
        if (resultCode == 1) {
            Intent i = getIntent();
            overridePendingTransition(0, 0);
            i.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
            finish();

            overridePendingTransition(0, 0);
            startActivity(i);
        }
    }
}

E na Atividade [B], ao clicar no botão:

setResult(1);
finish();
Kanika
fonte
ei, você queria terminar uma atividade da outra certo ... aí eu postei a resposta que está correta. Mas, por que você votou contra?
Manjunath
Há um tópico com algumas respostas interessantes aqui: stackoverflow.com/questions/14355731/…
ab

Respostas:

189
  1. Faça sua atividade A no arquivo de manifesto: launchMode = "singleInstance"

  2. Quando o usuário clicar em novo, faça FirstActivity.fa.finish();e chame o novo Intent.

  3. Quando o usuário clicar em modificar, chame o novo Intent ou simplesmente conclua a atividade B.

PRIMEIRA MANEIRA

Em sua primeira atividade, declare uma Activity objectcomo esta,

public static Activity fa;
onCreate()
{
    fa = this;
}

agora use esse objeto em outro Activitypara terminar a primeira atividade como esta,

onCreate()
{
    FirstActivity.fa.finish();
}

SEGUNDA MANEIRA

Ao chamar sua atividade FirstActivityque você deseja terminar assim que seguir em frente, você pode adicionar um sinalizador ao chamarFirstActivity

intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);

Mas, usando este sinalizador, a atividade será concluída mesmo se você não quiser. e às vezes, onBackse você quiser mostrar o FirstActivity, terá que chamá-lo usando a intenção.

MKJParekh
fonte
6
Ótima resposta..!!
Vaibhav Vajani
93
Você está mantendo uma referência estática a uma atividade. Isso nunca vai embora, a menos que você limpe manualmente de algum lugar -> você está criando um vazamento de memória!
DArkO
5
Bem, está tudo bem, você tem meu +1 para pensamento pronto para uso: D, eu apenas mudaria para singleTop. no entanto, ainda não será minha primeira escolha ao fazer algo semelhante. por código de limpeza eu quis dizer uma maneira de se livrar da referência estática para que não haja vazamento de memória, mas isso depende da estrutura do aplicativo.
DArkO
6
Por favor, ninguém use a primeira solução, é completamente errado. Você está contornando a estrutura do Android de uma forma realmente hacky enquanto cria um objeto zumbi. Use um BroadcastReceiver.
S-K
1
Soluções incríveis. Funcionou muito bem para o meu problema no qual eu estava indo das atividades A-> B-> C e no BackPressed de C, estava lançando uma nova instância de B. Mas se eu fizesse no BackPressed nessa nova instância de B, vá para a instância antiga de B em vez da instância antiga de A (o que eu queria). Então eu segui seu primeiro método no onBackPressed de C, e ele me deu o comportamento que eu queria :) Muito obrigado :)
SoulRayder
87

Isso você pode fazer, mas acho que não deve interromper o fluxo normal de atividade. Se quiser terminar a atividade, basta enviar uma transmissão da atividade B para a atividade A.

Crie um receptor de transmissão antes de iniciar sua atividade B:

BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {

    @Override
    public void onReceive(Context arg0, Intent intent) {
        String action = intent.getAction();
        if (action.equals("finish_activity")) {
            finish();
            // DO WHATEVER YOU WANT.
        }
    }
};
registerReceiver(broadcastReceiver, new IntentFilter("finish_activity"));

Envie a transmissão da atividade B para a atividade A quando quiser terminar a atividade A de B

Intent intent = new Intent("finish_activity");
sendBroadcast(intent);

Espero que funcione para você ...

Bharat Sharma
fonte
Ele mostra este erro "Erro de sintaxe em tokens, AnnotationName esperado" em "registerReceiver (broadcast_reciever, new IntentFilter (" finish_activity "));". O que há de errado?
Behzad
2
"você não deve interromper o fluxo normal de atividade" +1 para isso
S-K
11
Não se esqueça de cancelar o registro broadcast_receivercomunregisterReceiver()
Jaec
Esta é a solução. bom
Parinda Rajapaksha
17

Esta é uma questão de comunicação bastante comum. Uma abordagem seria usar um ResultReceiver na Atividade A:

Intent GotoB=new Intent(A.this,B.class);
GotoB.putExtra("finisher", new ResultReceiver(null) {
    @Override
    protected void onReceiveResult(int resultCode, Bundle resultData) {
        A.this.finish();
    }
});
startActivityForResult(GotoB,1);

e, em seguida, na Atividade B, você pode simplesmente concluí-la sob demanda, assim:

((ResultReceiver)getIntent().getExtra("finisher")).send(1, new Bundle());

Experimente algo assim.

Femi
fonte
6
+1 apenas, ((ResultReceiver) getIntent (). GetParcelableExtra ("finisher")). Send (1, new Bundle ());
Hamidreza Sadegh
12

Existe uma abordagem que você pode usar no seu caso.

Etapa 1: iniciar a atividade B a partir da atividade A

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

Passo 2: Se o usuário clicar no botão modificar, inicie a Atividade A usando o FLAG_ACTIVITY_CLEAR_TOP.Also, passe o sinalizador extra.

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "modify");
startActivity(i);
finish();

Passo 3: Se o usuário clicar no botão Adicionar, inicie a Atividade A usando o FLAG_ACTIVITY_CLEAR_TOP.Also, passe o sinalizador extra. FLAG_ACTIVITY_CLEAR_TOPirá limpar todas as atividades abertas até o alvo e reiniciar se nenhum modo de lançamento for definido na atividade alvo

Intent i = new Intent(B.this, A.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.putExtra("flag", "add");
startActivity(i);
finish();

Passo 4: Agora, onCreate()método da Atividade A, precisa recuperar esse sinalizador.

String flag = getIntent().getStringExtra("flag");
if(flag.equals("add")) {
    //Write a code for add
}else {
    //Write a code for modifying
}
Dharmendra
fonte
6

Comece sua atividade com o código de solicitação:

StartActivityForResult(intent,1234);

E você pode fechá-lo de qualquer outra atividade como esta:

finishActivity(1234);
Yaniv Maymon
fonte
Em que língua??
Morten Holmgaard
5

Veja minha resposta à pergunta Stack Overflow Concluir todas as atividades anteriores .

O que você precisa é adicionar o Intent.FLAG_CLEAR_TOP. Este sinalizador garante que todas as atividades acima da atividade de destino na pilha sejam concluídas e que uma seja mostrada.

Outra coisa de que você precisa é a SINGLE_TOPbandeira. Com este, você evita que o Android crie uma nova atividade se já houver uma criada na pilha.

Apenas fique atento, pois se a atividade já foi criada, o intent com esses sinalizadores será entregue no método chamado onNewIntent(intent)(você precisa sobrecarregá-lo para manipulá-lo) na atividade de destino.

Então, onNewIntentvocê tem um método chamado restart ou algo que irá chamar finish()e lançar uma nova intenção em relação a si mesmo, ou tem um repopulate()método que definirá os novos dados. Eu prefiro a segunda abordagem, é mais barata e você sempre pode extrair a onCreatelógica em um método separado que pode ser chamado para popular.

DArkO
fonte
4

Acabei de aplicar a solução do Nepster e funciona perfeitamente. Há uma pequena modificação para executá-lo a partir de um fragmento.

Para o seu fragmento

// sending intent to onNewIntent() of MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
intent.putExtra("transparent_nav_changed", true);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

E para o OnNewIntent () da Activity que você gostaria de reiniciar.

// recreate activity when transparent_nav was just changed
if (getIntent().getBooleanExtra("transparent_nav_changed", false)) {
    finish(); // finish and create a new Instance
    Intent restarter = new Intent(MainActivity.this, MainActivity.class);
    startActivity(restarter);
}
koras
fonte
2

Acho que tenho a abordagem mais fácil ... em pressionar novo em B ..

Intent intent = new Intent(B.this, A.class);
intent.putExtra("NewClicked", true);
 intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);

e em A pegue

  if (getIntent().getBooleanExtra("NewClicked", false)) {
        finish();// finish yourself and make a create a new Instance of yours.
      Intent intent = new Intent(A.this,A.class);
      startActivity(intent);
    }
Zar E Ahmer
fonte
1

Eu sei que esta é uma questão antiga, alguns desses métodos não funcionaram para mim, então para quem está procurando no futuro ou tendo meus problemas, isso funcionou para mim

Eu ignorei onPausee chamei finish()esse método.

Tony Kutzler
fonte
-1

Primeiro ligue e startactivity()depois usefinish()

Dharmik Ghori
fonte