Como programaticamente "reinicio" um aplicativo Android?

231

Em primeiro lugar, eu sei que não se deve realmente matar / reiniciar um aplicativo no Android. No meu caso de uso, desejo redefinir o aplicativo de fábrica em um caso específico em que um servidor envia uma informação específica ao cliente.

O usuário pode fazer login apenas no servidor com UMA instância do aplicativo (ou seja, vários dispositivos não são permitidos). Se outra instância obtiver o bloqueio "logado", todas as outras instâncias desse usuário terão que excluir seus dados (redefinição de fábrica), para manter a consistência.

É possível obter o bloqueio à força, porque o usuário pode excluir o aplicativo e reinstalá-lo, o que resultaria em um ID de instância diferente e o usuário não conseguiria mais liberar o bloqueio. Portanto, é possível obter o bloqueio à força.

Por causa dessa possibilidade de força, precisamos sempre verificar, em um caso concreto, se ela possui a trava. Isso é feito em (quase) cada solicitação ao servidor. O servidor pode enviar um "ID de bloqueio errado". Se isso for detectado, o aplicativo cliente deve excluir tudo.


Esse foi o caso de uso.

Eu tenho um ActivityA que inicia o Login ActivityL ou o ActivityB principal do aplicativo, dependendo de um valor sharedPrefs. Depois de iniciar L ou B, ele se fecha para que apenas L ou B esteja em execução. Portanto, no caso em que o usuário está logado, B já está sendo executado agora.

B inicia C. C chama startServiceo IntentServiceD. Isso resulta nessa pilha:

(A)> B> C> D

No método onHandleIntent de D, um evento é enviado para um ResultReceiver R.

R agora lida com esse evento, fornecendo ao usuário uma caixa de diálogo onde ele pode optar por redefinir o aplicativo de fábrica (excluir o banco de dados, sharedPrefs etc.)

Após a redefinição de fábrica, desejo reiniciar o aplicativo (para fechar todas as atividades) e iniciar somente A novamente, que inicia o logon ActivityL e termina:

(A)> L

O método onClick do Dialog se parece com o seguinte:

@Override
public void onClick(DialogInterface dialog, int which) {

    // Will call onCancelListener
    MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.)
    Intent i = new Intent(MyApp.getContext(), A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MyApp.getContext().startActivity(i);
}

E essa é a MyAppclasse:

public class MyApp extends Application {
    private static Context context;

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    public static Context getContext() {
        return context;
    }

    public static void factoryReset() {
        // ...
    }
}

O problema é que se eu usar FLAG_ACTIVITY_NEW_TASKas atividades B e C ainda estiverem em execução. Se eu apertar o botão voltar no login Activity, vejo C, mas quero voltar à tela inicial.

Se eu não definir FLAG_ACTIVITY_NEW_TASK, recebo o erro:

07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

Não posso usar as atividades ' Context, porque o ServiceIntentD também pode ser chamado a partir de uma tarefa em segundo plano iniciada pelo AlarmManager.

Então, como eu poderia resolver isso para a pilha de atividades se tornar (A)> L?

Preso
fonte

Respostas:

284

Você pode PendingIntentconfigurar para iniciar sua atividade inicial no futuro e depois fechar seu aplicativo

Intent mStartActivity = new Intent(context, StartActivity.class);
int mPendingIntentId = 123456;
PendingIntent mPendingIntent = PendingIntent.getActivity(context, mPendingIntentId,    mStartActivity, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
System.exit(0);
Oleg Koshkin
fonte
5
Isso funcionou perfeitamente para mim! Acabei de usar android.os.Process.killProcess (android.os.Process.myPid ()); sobre System.exit ();
FDIM 23/02
29
Nos dispositivos 4.3 e 4.4 (tudo que eu testei), isso parece eliminar a atividade atual e, em seguida, iniciar uma nova por cima da antiga. Eu tenho 2 atividades profundas (principal -> prefs). Pressionar para trás leva-me ao aplicativo antigo, uma tela para trás.
Mgamerz
5
No meu caso, System.exit (0) não funcionou porque uma transação estava sendo revertida. Em vez disso, usei activity.finish (); e funciona muito bem.
unifique
6
@Qulin, Pessoal! Você não pode estar falando sério! Este exemplo é mais como direção do que exemplo da vida real. Você precisa modificar esse snippet com o nome da atividade inicial, o ID de intenção e a mecânica de saída, independentemente do que estiver usando. Não copie cegamente cole-o.
precisa saber é o seguinte
19
Isso não funciona mais com o Android Q devido a novas restrições às atividades em segundo plano developer.android.com/preview/privacy/…
Marco Righini 20/19
103

Você pode simplesmente ligar para:

public static void triggerRebirth(Context context, Intent nextIntent) {
    Intent intent = new Intent(context, YourClass.class);
    intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(KEY_RESTART_INTENT, nextIntent);
    context.startActivity(intent);
    if (context instanceof Activity) {
      ((Activity) context).finish();
    }

    Runtime.getRuntime().exit(0);
}

Que é usado na biblioteca ProcessPhoenix


Como uma alternativa:

Aqui está uma versão um pouco melhorada da resposta do @Oleg Koshkin.

Se você realmente deseja reiniciar sua atividade, incluindo uma interrupção do processo atual, tente seguir o código. Coloque-o em uma HelperClass ou onde você precisar.

public static void doRestart(Context c) {
        try {
            //check if the context is given
            if (c != null) {
                //fetch the packagemanager so we can get the default launch activity 
                // (you can replace this intent with any other activity if you want
                PackageManager pm = c.getPackageManager();
                //check if we got the PackageManager
                if (pm != null) {
                    //create the intent with the default start activity for your application
                    Intent mStartActivity = pm.getLaunchIntentForPackage(
                            c.getPackageName()
                    );
                    if (mStartActivity != null) {
                        mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                        //create a pending intent so the application is restarted after System.exit(0) was called. 
                        // We use an AlarmManager to call this intent in 100ms
                        int mPendingIntentId = 223344;
                        PendingIntent mPendingIntent = PendingIntent
                                .getActivity(c, mPendingIntentId, mStartActivity,
                                        PendingIntent.FLAG_CANCEL_CURRENT);
                        AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
                        mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
                        //kill the application
                        System.exit(0);
                    } else {
                        Log.e(TAG, "Was not able to restart application, mStartActivity null");
                    }
                } else {
                    Log.e(TAG, "Was not able to restart application, PM null");
                }
            } else {
                Log.e(TAG, "Was not able to restart application, Context null");
            }
        } catch (Exception ex) {
            Log.e(TAG, "Was not able to restart application");
        }
    }

Isso também reinicializará as classes jni e todas as instâncias estáticas.

mikepenz
fonte
1
Essa solução é boa, mas atrasará alguns segundos até reiniciar o aplicativo, mesmo que você tenha diminuído os 100 milhões. No entanto, esta biblioteca ProcessPhoenix de Jack Wharton faz isso melhor e rapidamente, mas não vale a pena adicionar biblioteca apenas para esta função dentro do aplicativo.
blueware 22/08/16
@blueware Eu atualizei a minha resposta e acrescentou o código que é usado dentro ProcessPhonix
mikepenz
@mikepenz, esse cara "Ilya_Gazman" fez muito melhor e sem usar essa biblioteca.
blueware 22/08/16
3
@ blueware - exceto que a solução da Ilya não reiniciará o processo, portanto os dados estáticos ou as bibliotecas NDK carregadas não serão reinicializadas corretamente.
Ted Hopp
Alguns dispositivos Huawei e Samsung têm restrições AlarmManagere se comportam mal ao usar esta solução. Alguma abordagem melhor?
blueware 18/02
69

Jake Wharton publicou recentemente sua biblioteca ProcessPhoenix , que faz isso de uma maneira confiável. Você basicamente só precisa ligar para:

ProcessPhoenix.triggerRebirth(context);

A biblioteca concluirá automaticamente a atividade de chamada, interromperá o processo do aplicativo e reiniciará a atividade padrão do aplicativo posteriormente.

TBieniek
fonte
Isso parece funcionar, mas eu recebo uma falha (que é relatada). Não tenho certeza se isso é ideal.
BK-
1
Eu nunca tive problemas com a lib, mas fique
TBieniek
Argh, retiro meu comentário porque não olhei a mensagem de perto o suficiente. Faltava um filtro de intenção na minha atividade de inicialização padrão. Pode ser interessante notar os filtros de intenção exatos necessários.
precisa
1
Esta é até agora a melhor solução.
precisa saber é o seguinte
1
@ Shambhu, você precisa adicionar a tag <category android:name="android.intent.category.DEFAULT" />à atividade padrão <intent-filter> no manifesto do aplicativo.
Muhammed Refaat
57

Modifiquei ligeiramente a resposta Ilya_Gazman para usar novas APIs (o IntentCompat foi descontinuado ao iniciar a API 26). Runtime.getRuntime (). Exit (0) parece ser melhor que System.exit (0).

 public static void triggerRebirth(Context context) {
    PackageManager packageManager = context.getPackageManager();
    Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
    ComponentName componentName = intent.getComponent();
    Intent mainIntent = Intent.makeRestartActivityTask(componentName);
    context.startActivity(mainIntent);
    Runtime.getRuntime().exit(0);
}
android_dev
fonte
8
Diretamente dos documentos : " A chamada System.exit(n) é efetivamente equivalente à chamada: Runtime.getRuntime().exit(n) ". Internamente, System.exit()apenas vira e liga Runtime.getRuntime().exit(). Não há nada "melhor" em um ou no outro (a menos que se preocupe com a digitação de um ou com uma camada extra de chamadas de método).
Ted Hopp
onde e quando chamar o método acima?
Makvin
1
@ Makvin você decide onde chamá-lo. Meu caso foi reiniciar o aplicativo após a mudança de idioma.
Android_dev 11/08/19
O @TedHopp comenta todas as respostas como "não boas", você tem alguma solução viável? Não sendo sarcástico, realmente precisa recriar um aplicativo sem deixar vestígios; de variáveis ​​estáticas para instâncias de classe.
Farid
1
@FARID - Qualquer uma das soluções que envolvam chamadas Runtime.getRuntime().exit(0)(ou System.exit(0)) provavelmente funcionará. Alguns dos meus comentários "não bons" são para respostas (como a de Ilya Gazman, que foi editada para incorporar tal chamada.
Ted Hopp
37

IntentCompat.makeRestartActivityTask

A nova maneira de fazer isso é usando IntentCompat.makeRestartActivityTask

Crie um Intent que possa ser usado para reiniciar a tarefa de um aplicativo em seu estado base. É como makeMainActivity (ComponentName), mas também define os sinalizadores Intent.FLAG_ACTIVITY_NEW_TASK e FLAG_ACTIVITY_CLEAR_TASK.

PackageManager packageManager = context.getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage(context.getPackageName());
ComponentName componentName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(componentName);
context.startActivity(mainIntent);
System.exit(0);
Ilya Gazman
fonte
6
Isso relança a tarefa, mas não reinicia o processo ou mesmo o Applicationobjeto. Portanto, quaisquer staticdados, dados inicializados durante a criação das Applicationclasses, ou jni permanecem em seu estado atual e não são reinicializados.
Ted Hopp
2
@TedHopp Oh, eu perdi essa parte. Eu adicionei System.exit (0); Mas não tenho 100% de certeza de que funcionará. Vou testá-lo posteriormente em
Ilya Gazman 14/03
1
A melhor solução sem usar a biblioteca de código aberto para fazer isso. Mãos ao alto e obrigado por fornecer esta resposta, +1
blueware
4
Infelizmente, IntentCompat.makeRestartActivityTaskagora está obsoleto . Se você inspecionar o código fonte , é tão simples quanto simplesmente adicionar os sinalizadores Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.
Paul Lammertsma
IntentCompat.makeRestartActivityTask removido
luckyhandler
28

Existe um truque muito bom. Meu problema era que algumas bibliotecas jni C ++ realmente antigas vazavam recursos. Em algum momento, ele parou de funcionar. O usuário tentou sair do aplicativo e iniciá-lo novamente - sem resultado, porque terminar uma atividade não é o mesmo que terminar (ou matar) o processo. (A propósito, o usuário pode ir para a lista de aplicativos em execução e parar a partir daí - isso funcionaria, mas os usuários simplesmente não sabem como finalizar aplicativos.)

Se você quiser observar o efeito desse recurso, adicione uma staticvariável à sua atividade e aumente cada uma, digamos, pressione o botão. Se você sair da atividade do aplicativo e depois invocá-lo novamente, essa variável estática manterá seu valor. (Se o aplicativo realmente fosse encerrado, a variável receberia o valor inicial.)

(E eu tenho que comentar por que eu não quis corrigir o bug. A biblioteca foi escrita décadas atrás e vazou recursos desde então. A gerência acredita que sempre funcionou . O custo de fornecer uma correção em vez de uma solução alternativa ... Eu acho que você entendeu.)

Agora, como eu poderia redefinir uma biblioteca compartilhada jni (também conhecida como .so) para o estado inicial? Eu escolhi reiniciar o aplicativo como um novo processo.

O truque é que System.exit () fecha a atividade atual e o Android recria o aplicativo com uma atividade a menos.

Então o código é:

/** This activity shows nothing; instead, it restarts the android process */
public class MagicAppRestart extends Activity {
    // Do not forget to add it to AndroidManifest.xml
    // <activity android:name="your.package.name.MagicAppRestart"/>
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        System.exit(0);
    }
    public static void doRestart(Activity anyActivity) {
        anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
    }
}

A atividade de chamada apenas executa o código MagicAppRestart.doRestart(this);, a atividade de chamada onPause()é executada e, em seguida, o processo é recriado. E não se esqueça de mencionar esta atividade no AndroidManifest.xml

A vantagem deste método é que não há atrasos.

UPD: funcionou no Android 2.x, mas no Android 4 algo mudou.

18446744073709551615
fonte
3
eu usei activity.startActivity (i); System.exit (0); genius solution
max4ever 27/11/2012
5
Esta solução fecha o aplicativo para mim, mas não é reiniciado. Pelo menos no Android 4.3.
Kirill Rakhman
1
No Samsung Galaxy Mega Android 4.2.2, causa um loop infinito de reinicialização. Portanto, o aplicativo não será iniciado novamente.
Gunhan
@ Gunhan 1) o que acontece se você substituir System.exit(0)por android.os.Process.killProcess(android.os.Process.myPid());? 2) um loop infinito provavelmente significa que eles não removem a atividade superior quando reiniciam um aplicativo. Em princípio, você pode adicionar uma variável booleana estática, configurá-la como true antes de chamar a atividade de reinicialização e, após a reinicialização, ela será falsa. Assim, a atividade pode descobrir se o reinício já ocorreu (e se ocorreu, basta finalizar () ). OTOH, seu relatório significa que o truque não funciona de forma idêntica em todos os dispositivos.
18446744073709551615
@ Gunham Se você estiver iniciando a mesma atividade que está causando a reinicialização, haverá um loop infinito em qualquer dispositivo.
Lukas Hanacek
23

Minha solução não reinicia o processo / aplicativo. Ele permite apenas que o aplicativo "reinicie" a atividade em casa (e descarte todas as outras atividades). Parece uma reinicialização para os usuários, mas o processo é o mesmo. Eu acho que em alguns casos as pessoas querem alcançar esse efeito, então apenas deixo aqui para a sua informação.

public void restart(){
    Intent intent = new Intent(this, YourHomeActivity.class);
    this.startActivity(intent);
    this.finishAffinity();
}
yongsunCN
fonte
15

Ok, refatorei meu aplicativo e não terminarei A automaticamente. Eu deixo isso correr sempre e termino no onActivityResultevento. Dessa forma, posso usar os sinalizadores FLAG_ACTIVITY_CLEAR_TOP+ FLAG_ACTIVITY_NEW_TASKpara obter o que quero:

public class A extends Activity {

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        finish();
    }

    protected void onResume() {
        super.onResume();
        // ...
        if (loggedIn) {
            startActivityForResult(new Intent(this, MainActivity.class), 0);
        } else {
            startActivityForResult(new Intent(this, LoginActivity.class), 0);
        }
    }
}

E no ResultReceiver

@Override
public void onClick(DialogInterface dialog, int which) {
    MyApp.factoryReset();
    Intent i = new Intent(MyApp.getContext(), A.class);
    i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    MyApp.getContext().startActivity(i);
}

Obrigado mesmo assim!

Preso
fonte
23
Isso não reiniciará o aplicativo, apenas recriará as classes. Portanto, quaisquer variáveis ​​estáticas nas classes reterão valores das execuções anteriores.
Brian White
14
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Nirav Ranpara
fonte
24
Isso não reiniciará o aplicativo, apenas recriará as classes. Portanto, qualquer variável estática dentro das classes reterá valores das execuções anteriores.
Brian White
14

O único código que não acionou "Seu aplicativo foi fechado inesperadamente" é o seguinte. Também é um código não obsoleto que não requer uma biblioteca externa. Também não requer um temporizador.

public static void triggerRebirth(Context context, Class myClass) {
    Intent intent = new Intent(context, myClass);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
    context.startActivity(intent);
    Runtime.getRuntime().exit(0);
}
Haskell McRavin
fonte
8

Descobri que isso funciona na API 29 e posterior - com o objetivo de matar e reiniciar o aplicativo como se o usuário o tivesse lançado quando não estava em execução.

public void restartApplication(final @NonNull Activity activity) {
   // Systems at 29/Q and later don't allow relaunch, but System.exit(0) on
   // all supported systems will relaunch ... but by killing the process, then
   // restarting the process with the back stack intact. We must make sure that
   // the launch activity is the only thing in the back stack before exiting.
   final PackageManager pm = activity.getPackageManager();
   final Intent intent = pm.getLaunchIntentForPackage(activity.getPackageName());
   activity.finishAffinity(); // Finishes all activities.
   activity.startActivity(intent);    // Start the launch activity
   System.exit(0);    // System finishes and automatically relaunches us.
}

Isso foi feito quando a atividade do iniciador no aplicativo tem o seguinte:

<intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <action android:name="android.intent.action.MAIN" />
    <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>

Vi comentários alegando que uma categoria de PADRÃO é necessária, mas não achei que fosse esse o caso. Confirmei que o objeto Aplicativo no meu aplicativo foi recriado, por isso acredito que o processo realmente foi morto e reiniciado.

O único objetivo para o qual eu uso isso é reiniciar o aplicativo depois que o usuário tiver ativado ou desativado o relatório de falhas do Firebase Crashlytics. De acordo com os documentos, o aplicativo precisa ser reiniciado (processo eliminado e recriado) para que essa alteração entre em vigor.

Mark Peters
fonte
7

A melhor maneira de reiniciar completamente um aplicativo é reiniciá-lo, não apenas para ir para uma atividade com FLAG_ACTIVITY_CLEAR_TOPe FLAG_ACTIVITY_NEW_TASK. Portanto, minha solução é fazer isso no seu aplicativo ou mesmo em outro aplicativo, a única condição é saber o nome do pacote do aplicativo (exemplo: ' com.example.myProject ')

 public static void forceRunApp(Context context, String packageApp){
    Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageApp);
    launchIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(launchIntent);
}

Exemplo de uso reinicie ou inicie o appA do appB :

forceRunApp(mContext, "com.example.myProject.appA");

Você pode verificar se o aplicativo está sendo executado:

 public static boolean isAppRunning(Context context, String packageApp){
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
    for (int i = 0; i < procInfos.size(); i++) {
        if (procInfos.get(i).processName.equals(packageApp)) {
           return true;
        }
    }
    return false;
}

Nota : Eu sei que esta resposta está um pouco fora de tópico, mas pode ser realmente útil para alguém.

Choletski
fonte
5

Minha melhor maneira de reiniciar o aplicativo é usar o finishAffinity();
Since, que finishAffinity();pode ser usado apenas nas versões JELLY BEAN, para que possamos usarActivityCompat.finishAffinity(YourCurrentActivity.this); nas versões inferiores.

Em seguida, use Intentpara iniciar a primeira atividade, para que o código fique assim:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
    finishAffinity();
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
} else {
    ActivityCompat.finishAffinity(YourCurrentActivity.this);
    Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
    startActivity(intent);
}

Espero que ajude.

Hussein ND
fonte
1
Isso encerra todas as atividades na tarefa atual, mas não reinicia o processo nem cria novamente o objeto Aplicativo. Portanto, quaisquer dados estáticos, dados inicializados durante a criação do Aplicativo ou por classes jni, permanecem em seu estado atual e não são reinicializados.
Ted Hopp
3

Tente usar FLAG_ACTIVITY_CLEAR_TASK

Pedro Loureiro
fonte
hm desenvolvimento para 2.1: Intent.FLAG_ACTIVITY_CLEAR_TASK não pode ser resolvido
Preso
Desculpe - Desde: API Nível 11 developer.android.com/reference/android/content/…
Pedro Loureiro
3

Aqui está um exemplo para reiniciar seu aplicativo de maneira genérica usando o PackageManager:

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Alireza Ghanbarinia
fonte
Isso relança a tarefa, mas não reinicia o processo ou mesmo o Applicationobjeto. Portanto, quaisquer dados estáticos, dados inicializados durante a criação das Applicationclasses, ou jni permanecem em seu estado atual e não são reinicializados.
Ted Hopp
3

tente isto:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
Veeson
fonte
1
Como todas as outras respostas aqui já sugerem a mesma coisa, isso não reiniciará o aplicativo, apenas recriará as classes. Portanto, quaisquer dados estáticos no processo não serão redefinidos.
Ted Hopp
2

Inicie diretamente a tela inicial com FLAG_ACTIVITY_CLEAR_TASKe FLAG_ACTIVITY_NEW_TASK.

Yijun Li
fonte
2

Eu tive que adicionar um manipulador para atrasar a saída:

 mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 200, mPendingIntent);
        final Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Runtime.getRuntime().exit(0);
            }
        }, 100);
Andy7229082
fonte
2

Usar:

navigateUpTo(new Intent(this, MainActivity.class));

Funciona a partir do nível 16 da API (4.1), acredito.

Peter Mortensen
fonte
1

Você pode usar o startInstrumentationmétodo de Activity. Você precisa implementar vazio Instrumentatione apontado no manifesto. Depois disso, você pode chamar esse método para reiniciar seu aplicativo. Como isso:

try {           
    InstrumentationInfo info = getPackageManager().queryInstrumentation(getPackageName(), 0).get(0);
    ComponentName component = new ComponentName(this, Class.forName(info.name));
    startInstrumentation(component, null, null);
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Recebo o nome da classe Instrumentation dinamicamente, mas você pode codificá-lo. Alguns assim:

try {           
    startInstrumentation(new ComponentName(this, RebootInstrumentation.class), null, null); 
} catch (Throwable e) {             
    new RuntimeException("Failed restart with Instrumentation", e);
}

Ligue para startInstrumentationfazer a recarga do seu aplicativo. Leia a descrição deste método. Mas pode não ser seguro se agir como um aplicativo matador.

Enyby
fonte
1

O aplicativo em que estou trabalhando tem que dar ao usuário a possibilidade de escolher quais fragmentos exibir (os fragmentos são alterados dinamicamente no tempo de execução). A melhor solução para mim foi reiniciar completamente o aplicativo.

Então, eu tentei muitas soluções e nenhuma delas funcionou para mim, mas isso:

final Intent mStartActivity = new Intent(SettingsActivity.this, Splash.class);
final int mPendingIntentId = 123456;
final PendingIntent mPendingIntent = PendingIntent.getActivity(SettingsActivity.this, mPendingIntentId, mStartActivity,
                    PendingIntent.FLAG_CANCEL_CURRENT);
final AlarmManager mgr = (AlarmManager) SettingsActivity.this.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
this.finishAffinity(); //notice here
Runtime.getRuntime().exit(0); //notice here

Esperando que isso ajude alguém!

hzitoun
fonte
0

tente isto:

private void restartApp() {
    Intent intent = new Intent(getApplicationContext(), YourStarterActivity.class);
    int mPendingIntentId = MAGICAL_NUMBER;
    PendingIntent mPendingIntent = PendingIntent.getActivity(getApplicationContext(), mPendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
    AlarmManager mgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
    System.exit(0);
}
Muhammad Mubeen
fonte
-1

Com a biblioteca Process Phoenix . A atividade que você deseja relançar é denominada "A".

Sabor Java

// Java
public void restart(){
    ProcessPhoenix.triggerRebirth(context);
}

Sabor Kotlin

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}
Raymond Chenon
fonte
Isso tem o resultado infeliz de desconectar o depurador.
DrSatan1 26/02
-3

Você pode reiniciar sua atividade atual assim:

Fragmento:

activity?.recreate()

Atividade:

recreate()

fonte
3
Isso não é o que o OP quer fazer.
Ted Hopp