Como reiniciar a atividade no Android

381

Como reinicio um Android Activity? Eu tentei o seguinte, mas o Activitysimplesmente sai.

public static void restartActivity(Activity act){

        Intent intent=new Intent();
        intent.setClass(act, act.getClass());
        act.startActivity(intent);
        act.finish();

}
Samet ÖZTOPRAK
fonte
9
a atividade é encerrada porque você chamou "act.finish ();" imediatamente depois de criar a atividade ...
Nikhil Dinesh
11
método desatualizado
pedjjj 14/01

Respostas:

623

Eu fiz o meu alternador de temas assim:

Intent intent = getIntent();
finish();
startActivity(intent);

Basicamente, estou ligando finish()primeiro e usando exatamente a mesma intenção com a qual essa atividade foi iniciada. Isso parece fazer o truque?

ATUALIZAÇÃO: Conforme apontado por Ralf abaixo, Activity.recreate()é o caminho a seguir na API 11 e além. Isso é preferível se você estiver em um ambiente API11 +. Você ainda pode verificar a versão atual e chamar o snippet de código acima, se estiver na API 10 ou abaixo. (Por favor, não esqueça de votar de novo na resposta de Ralf!)

EboMike
fonte
36
E isso vale a pena ser votado? Esse não era um requisito mencionado pelo OP. De fato, isso pode ser desejado.
EboMike 11/05
9
Bem, se você não gosta da animação, pode desativá-la (como demonstrou na sua resposta). Isso não faz minha resposta errada por si só, apenas mostra algumas opções adicionais que você pode adicionar (e isso não foi solicitado na pergunta).
EboMike
28
Eu acho que você entendeu errado. Um voto negativo significa resposta errada / ruim, e voto positivo significa que uma resposta é ótima. Quão grande é uma resposta comparada com outras é indicada pelo número de votos positivos. Percebo que você está tentando promover sua resposta, mas está usando mal o sistema para esse fim.
EboMike 12/05
8
+1 - isso funcionou muito bem para mim e, como você diz, a animação é algo que eu queria, para que o usuário saiba que está reiniciando. FWIW, eu costumo estabelecer uma regra para nunca fazer o voto negativo nas respostas de outros usuários quando forneço uma resposta alternativa para a pergunta, embora ocasionalmente faça votos positivos quando minha resposta for ultrapassada (sem dizer que aconteceu aqui, apenas o faço) .
Michael Bray
4
EboMike e Ben: Ambas as suas soluções responderam à pergunta do OP. Votar a resposta de alguém puramente por causa da razão "estética" não é bom. Eu iria desencorajar ninguém a fazê-lo aqui na Stackoverflow ...
ChuongPham
368

Desde o nível 11 da API (Honeycomb), você pode chamar o método recreate () da atividade (graças a esta resposta).

O método recrte () atua como uma alteração na configuração, portanto, os métodos onSaveInstanceState () e onRestoreInstanceState () também são chamados, se aplicável.

Ralf
fonte
3
e se a atividade anterior a chamou usando startActivityForResult?
desenvolvedor android
11
Bem, é a resposta correta se você não precisa oferecer suporte a algo menor que a API 11.
Edward Falk
@ EdwardFalk existe alguma função que faz isso na biblioteca de suporte?
desenvolvedor android
2
Isso não funciona em todos os casos. Se você tiver uma gaveta de navegação aberta ao chamar recrear (), ela permanecerá aberta quando recriada, o que significa que salva o estado, o que pode não ser desejável.
Chapz
Fui eu quem não quer que o estado seja salvo. Às vezes, as pessoas querem apenas um reinício limpo, então devem usar a resposta do EboMike.
Kimi Chiu
132

Antes do SDK 11, uma maneira de fazer isso é:

public void reload() {
    Intent intent = getIntent();
    overridePendingTransition(0, 0);
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);
    startActivity(intent);
}
Ben
fonte
No HTC Desire, as animações ainda permanecem (pelo menos quando usadas no método onConfigurationChanged). Eles não ocorrem sempre, mas usando o código do EboMike, eles também não ocorrem sempre.
Juozas Kontvainis
8
Isso não funciona na atividade principal iniciada pelo iniciador. Sua atividade acabará oculta por causa de alguns dos sinalizadores definidos na intenção. Caso contrário, ele funciona bem.
Thomas Ahle
Bom ponto. faz sentido porque chama finish () da atividade base na pilha.
Ben
Chamar esse, enquanto nós mudar o tema da Atividade parece trazer para fora a velocidade (sem animações)
Ashok Goli
3
+1 Funciona bem, para mim, mesmo com a Atividade principal. No entanto, você deve ligar overridePendingTransition(0, 0);depois finish()e startActivity(), respectivamente, não onde você chamou-lhe ...
caw
115

Apenas para combinar as respostas de Ralf e Ben (incluindo as alterações feitas nos comentários):

if (Build.VERSION.SDK_INT >= 11) {
    recreate();
} else {
    Intent intent = getIntent();
    intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
    finish();
    overridePendingTransition(0, 0);

    startActivity(intent);
    overridePendingTransition(0, 0);
}
JustinMorris
fonte
8
Melhor resposta de todas. Acredite ou não, porém, eu ainda estou apoiando API 3 dispositivos, eo valor VERSION.SDK_INT requer API 4. :)
Edward Falk
31

Eu usei esse código para poder suportar versões mais antigas do Android e usar recreate() -las em versões mais recentes do Android.

Código:

public static void restartActivity(Activity activity){
    if (Build.VERSION.SDK_INT >= 11) {
        activity.recreate();
    } else {
        activity.finish();
        activity.startActivity(activity.getIntent());
    }
}

Amostra:

import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity {
    private Activity mActivity;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mActivity = MainActivity.this;

        Button button = (Button) findViewById(R.id.restart_button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                restartActivity(mActivity);
            }
        });
    }

    public static void restartActivity(Activity activity) {
        if (Build.VERSION.SDK_INT >= 11) {
            activity.recreate();
        } else {
            activity.finish();
            activity.startActivity(activity.getIntent());
        }
    }
}
Thomas Vos
fonte
é um ótimo trabalho para mim !!
papo
22

Esta solução funcionou para mim.

Primeiro termine a atividade e depois inicie-a novamente.

Código de amostra:

public void restartActivity(){
    Intent mIntent = getIntent();
    finish();
    startActivity(mIntent);
}
user3748515
fonte
20

Essa é de longe a maneira mais fácil de reiniciar a atividade atual:

finish();
startActivity(getIntent());
Abhishek Soni
fonte
19

Chame este método

private void restartFirstActivity()
 {
 Intent i = getApplicationContext().getPackageManager()
 .getLaunchIntentForPackage(getApplicationContext().getPackageName() );

 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK );
 startActivity(i);
 }

Obrigado,

Nikhil Dinesh
fonte
11
Acho que o OP quer reiniciar qualquer atividade, não apenas a primeira, mas isso foi útil para mim.
Kristopher Johnson
11
As duas bandeiras são boas de saber, meu caso parecia não fazer nada sem elas.
Owen B
11
funcionou graças a você! Deus te abençoê .
Vivek
16

Mesmo que isso tenha sido respondido várias vezes.

Se reiniciar uma atividade de um fragmento, eu faria assim:

new Handler().post(new Runnable() {

         @Override
         public void run()
         {
            Intent intent = getActivity().getIntent();
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_ANIMATION);
            getActivity().overridePendingTransition(0, 0);
            getActivity().finish();

            getActivity().overridePendingTransition(0, 0);
            startActivity(intent);
        }
    });

Então você pode estar pensando que isso é um pouco exagerado? Mas a Handlerpostagem permite que você chame isso em um método de ciclo de vida. Eu usei isso em onRestart/onResume methods ao verificar se o estado mudou entre o usuário que volta ao aplicativo. (instalei algo).

Sem o Handler se você o chamar em um local estranho, ele simplesmente matará a atividade e não a reiniciará.

Sinta-se a vontade para fazer qualquer pergunta.

Cheers, Chris

Chris.Jenkins
fonte
2
Ótima solução e muito bom raciocínio / explicação para o manipulador.
JRomero
11
Por que você chama duas vezes para "overridePendingTransition"?
desenvolvedor android
11
@androiddeveloper Não me lembro, acho que foi uma solução para um bug. Você pode chamá-lo uma vez antes de startActivity () e fará o que foi dito.
Chris.Jenkins
Depois de implementar isso na minha função onResume, o jogo para no meu método onStop e tem uma tela preta ... não sei por que
#
11
Oi chris, você pode explicar um pouco mais "Sem o manipulador, se você o chamar em um local estranho, ele simplesmente matará a atividade e não a reiniciará." ?
parvez rafi
15

Bem, isso não está listado, mas uma combinação de alguns que já foram publicados:

if (Build.VERSION.SDK_INT >= 11) {
    recreate();   
} else {
    Intent intent = getIntent();
    finish();
    startActivity(intent);
}
Codeversed
fonte
Funciona para mim .. obrigado .. mas quero perguntar: por que quando removo a primeira parte do código (a que verifica o SDK_INT) meu aplicativo é executado, relativamente lento? !! .. quando eu recoloco o código novamente, ele é executado relativamente e obviamente muito mais rápido !!!
22413 McLan
2
Não tenho certeza disso. Bem, se você estiver usando um SDK que é> = 11, recrie () deve ser mais rápido do que obter intenção, concluir e iniciá-lo novamente. Conclua as chamadas de código executado no onStop e recrie o código de execução como mudança de orientação ... portanto, não há muito o que fazer.
Codeversed
4

Em conjunto com o estranho comportamento do ciclo de vida do SurfaceView com a câmera . Descobri que recreate () não se comporta bem com o ciclo de vida do SurfaceViews. surfaceDestroyed nunca é chamado durante o ciclo de recreação. É chamado após onResume (estranho), momento em que meu SurfaceView é destruído.

A maneira original de recriar uma atividade funciona bem.

Intent intent = getIntent();
finish();
startActivity(intent);

Não consigo descobrir exatamente por que isso ocorre, mas é apenas uma observação que, esperançosamente, pode guiar outras pessoas no futuro, porque corrigiu meus problemas que eu estava tendo com o SurfaceViews

The4thIceman
fonte
4

Eu me pergunto por que ninguém mencionou Intent.makeRestartActivityTask()que faz exatamente esse propósito exato.

Crie um Intent que possa ser usado para reiniciar a tarefa de um aplicativo * em seu estado base.

startActivity(Intent.makeRestartActivityTask(getActivity().getIntent().getComponent()));

Este método define Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASKcomo sinalizadores padrão.

shkschneider
fonte
3

Na verdade, o código a seguir é válido para os níveis 5 e superior da API; portanto, se sua API de destino for menor que isso, você terá algo muito semelhante ao código do EboMike.

intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
overridePendingTransition(0, 0);
Sandy
fonte
3

Existe uma maneira hacky que deve funcionar em qualquer atividade, incluindo a principal.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);

Quando a orientação muda, o Android geralmente recria sua atividade (a menos que você a substitua). Este método é útil para rotações de 180 graus, quando o Android não recriar sua atividade.

Achal Dave
fonte
3
public void onRestart() {
    super.onRestart();
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    finish();
    act.startActivity(intent);
}

tente usar isso ..

Amsheer
fonte
3

A solução para sua pergunta é:

public static void restartActivity(Activity act){
    Intent intent=new Intent();
    intent.setClass(act, act.getClass());
    ((Activity)act).startActivity(intent);
    ((Activity)act).finish();
}

Você precisa converter no contexto da atividade para iniciar uma nova atividade e também para concluir a atividade atual.

Espero que seja útil .. e funcione para mim.

Rajesh Peram
fonte
1

Se você remover a última linha, criará uma nova actatividade, mas sua instância antiga ainda estará ativa.

Você precisa reiniciar a atividade como quando a orientação é alterada (ou seja, seu estado é salvo e passado para onCreate(Bundle))?

Caso contrário, uma solução alternativa possível seria usar uma atividade fictícia extra, que seria iniciada a partir da primeira atividade e qual tarefa iniciaria uma nova instância dela. Ou apenas adie a chamada paraact.finish() depois que a nova for iniciada.

Se você precisa salvar a maior parte do estado, está entrando em águas muito profundas, porque não é trivial passar todas as propriedades do seu estado, especialmente sem vazar seu antigo Contexto / Atividade, passando-o para a nova instância.

Por favor, especifique o que você está tentando fazer.

Dimitar Dimitrov
fonte
11
Eu tenho um botão que aplica temas diferentes ao aplicativo, depois que o tema é aplicado, ele é salvo na preferência, a atividade raiz é reiniciada, lê o tema da preferência, aplica o tema no onCreate (). Acontece que o código acima funciona bem se a atividade não é de instância única. Não tenho certeza se essa é a melhor prática.
Atualmente, não há nenhuma maneira limpa, SDK-pavimentada para reiniciar sua atividade, AFAIK - se você fizer qualquer coisa não vazamento, pode ser bom para ir :)
Dimitar Dimitrov
0

É assim que eu faço.

        val i = Intent(context!!, MainActivity::class.java)
        i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK)
        startActivity(i)
MicroRJ
fonte
-1

Se você estiver chamando de algum fragmento, faça o código abaixo.

Intent intent = getActivity().getIntent();
getActivity().finish();
startActivity(intent);
Mihir Trivedi
fonte
-4

você pode simplesmente usar

onRestart ()

método da seguinte maneira

 @Override
    protected void onRestart() {
        super.onRestart();
        setContentView(R.layout.add_entry);
    }

e ligue para onRestart () onde deseja reiniciar a atividade atual

SuKu
fonte
-5

Chame o método onCreate. Por exemploonCreate(null);

kike0kike
fonte