¿Cómo “reinicio” programáticamente una aplicación de Android?

231

En primer lugar, sé que uno no debería realmente matar / reiniciar una aplicación en Android. En mi caso de uso, quiero restablecer de fábrica mi aplicación en un caso específico donde un servidor envía una información específica al cliente.

El usuario solo puede iniciar sesión en el servidor con UNA instancia de la aplicación (es decir, no se permiten varios dispositivos). Si otra instancia obtiene ese bloqueo de "inicio de sesión", todas las demás instancias de ese usuario deben eliminar sus datos (restablecimiento de fábrica) para mantener la coherencia.

Es posible obtener el bloqueo por la fuerza, porque el usuario puede eliminar la aplicación y volver a instalarla, lo que daría como resultado una identificación de instancia diferente y el usuario ya no podrá liberar el bloqueo. Por lo tanto, es posible obtener el bloqueo por la fuerza.

Debido a esa posibilidad de fuerza, debemos verificar siempre en una instancia concreta que tiene el bloqueo. Eso se hace en (casi) cada solicitud al servidor. El servidor puede enviar una "identificación de bloqueo incorrecta". Si se detecta eso, la aplicación cliente debe eliminar todo.


Ese fue el caso de uso.

Tengo una ActivityA que inicia el inicio de sesión ActivityL o la ActivityB principal de la aplicación dependiendo de un valor sharedPrefs. Después de iniciar L o B, se cierra solo para que solo L o B se esté ejecutando. Entonces, en el caso de que el usuario haya iniciado sesión, B ya se está ejecutando.

B comienza C. C llama startServicea la IntentServiceD. Eso da como resultado esta pila:

(A)> B> C> D

Desde el método onHandleIntent de D se envía un evento a un ResultReceiver R.

R ahora maneja ese evento al proporcionar al usuario un cuadro de diálogo donde puede elegir restablecer la aplicación de fábrica (eliminar la base de datos, sharedPrefs, etc.)

Después del restablecimiento de fábrica, quiero reiniciar la aplicación (para cerrar todas las actividades) y solo iniciar A nuevamente, que luego inicia el inicio de sesión ActivityL y finaliza:

(A)> L

El método onClick del diálogo se ve así:

@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);
}

Y esa es la MyAppclase:

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() {
        // ...
    }
}

El problema es si uso FLAG_ACTIVITY_NEW_TASKlas actividades B y C que aún se están ejecutando. Si presiono el botón Atrás en el inicio de sesión Activity, veo C, pero quiero volver a la pantalla de inicio.

Si no configuro FLAG_ACTIVITY_NEW_TASK, aparece el error:

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?

No puedo usar las Actividades ' Context, porque la ServiceIntentD también podría llamarse desde una tarea en segundo plano que es iniciada por AlarmManager.

Entonces, ¿cómo podría resolver esto con la pila de actividades convirtiéndose en (A)> L?

Atascado
fuente

Respuestas:

284

Puede usarlo PendingIntentpara configurar el inicio de su actividad de inicio en el futuro y luego cerrar su aplicación

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
fuente
55
¡Esto funcionó perfectamente para mí! Acabo de usar android.os.Process.killProcess (android.os.Process.myPid ()); sobre System.exit ();
FDIM
29
En los dispositivos 4.3 y 4.4 (todo lo que he probado) esto parece matar la actividad actual y luego lanzar una nueva sobre la anterior. Tengo 2 actividades profundas (principal -> prefs). Presionar hacia atrás me lleva a la aplicación anterior, una pantalla hacia atrás.
Mgamerz
55
En mi caso, System.exit (0) no funcionó ya que una transacción estaba retrocediendo. En su lugar, utilicé activity.finish (); Y funciona bien.
unifique
66
@Qulin, chicos! ¡No puedes hablar en serio! Este ejemplo se parece más a la dirección que a la vida real. Debe modificar este fragmento con el nombre de la actividad de inicio, el ID de intención y la mecánica de salida, lo que sea que desee. No copie a ciegas y péguelo.
Oleg Koshkin
19
Esto ya no funciona con Android Q debido a nuevas restricciones a las actividades en segundo plano developer.android.com/preview/privacy/…
Marco Righini
103

Simplemente puede llamar:

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 se usa en la biblioteca ProcessPhoenix


Como alternativa:

Aquí hay una versión un poco mejorada de la respuesta de @Oleg Koshkin.

Si realmente desea reiniciar su actividad, incluida la eliminación del proceso actual, intente con el siguiente código. Colóquelo en una HelperClass o donde lo necesite.

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");
        }
    }

Esto también reinicializará las clases jni y todas las instancias estáticas.

Mikepenz
fuente
1
Esta solución es buena, pero se retrasará unos segundos hasta que reinicie su aplicación, incluso si disminuyó los 100 Millis. Sin embargo, esta biblioteca ProcessPhoenix de Jack Wharton lo hace mejor y rápidamente, pero no vale la pena agregar una biblioteca solo para esta función dentro de la aplicación.
blueware
@blueware He actualizado mi respuesta y agregué el código que se usa dentro de ProcessPhonix
mikepenz
@mikepenz, a este tipo "Ilya_Gazman" le fue mucho mejor y sin usar esa biblioteca.
blueware
3
@blueware: excepto que la solución de Ilya no reiniciará el proceso, por lo que los datos estáticos o las bibliotecas NDK cargadas no se reiniciarán correctamente.
Ted Hopp
Algunos dispositivos Huawei y Samsung tienen restricciones AlarmManagery se comportan mal si usan esta solución. ¿Algún mejor enfoque?
blueware
69

Jake Wharton publicó recientemente su biblioteca ProcessPhoenix , que hace esto de manera confiable. Básicamente solo tienes que llamar:

ProcessPhoenix.triggerRebirth(context);

La biblioteca finalizará automáticamente la actividad de llamada, cerrará el proceso de la aplicación y luego reiniciará la actividad de la aplicación predeterminada.

TBieniek
fuente
Esto parece funcionar, pero tengo un bloqueo (que se informa). No estoy seguro de que esto sea ideal.
BK-
1
Nunca tuve problemas con la biblioteca, pero siéntase libre de informar un error en github.com/JakeWharton/ProcessPhoenix/issues
TBieniek
Argh, retracto mi comentario ya que no miré el mensaje lo suficientemente cerca. Me faltaba un filtro de intención en mi actividad de inicio predeterminada. Puede valer la pena señalar los filtros de intención exactos requeridos.
BK-
1
Esta es hasta ahora la mejor solución.
yongsunCN
1
@Shambhu, debe agregar la etiqueta <category android:name="android.intent.category.DEFAULT" />a su actividad predeterminada <intent-filter> en el manifiesto de la aplicación.
Muhammed Refaat
57

He modificado ligeramente la respuesta de Ilya_Gazman para usar nuevas API (IntentCompat está en desuso a partir de la API 26). Runtime.getRuntime (). Exit (0) parece ser mejor 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
fuente
8
Directamente de los documentos : " La llamada System.exit(n) es efectivamente equivalente a la llamada: Runtime.getRuntime().exit(n) ". Internamente, System.exit()solo se da vuelta y llama Runtime.getRuntime().exit(). No hay nada "mejor" acerca de uno u otro (a menos que uno esté preocupado por cuánto escribe uno o por una capa adicional de llamadas a métodos).
Ted Hopp
¿Dónde y cuándo llamar al método anterior?
Makvin
1
@Makvin, tú decides dónde llamarlo. Mi caso fue reiniciar la aplicación después del cambio de idioma.
android_dev
@TedHopp ha estado comentando cada respuesta como "no buena", ¿tiene alguna solución factible? No siendo sarcástico, realmente necesito recrear una aplicación sin dejar rastro; desde variables estáticas hasta instancias de clase.
Farid
1
@FARID: cualquiera de las soluciones que implican llamadas Runtime.getRuntime().exit(0)(o System.exit(0)) probablemente funcionará. Algunos de mis comentarios "no buenos" son para respuestas (como el de Ilya Gazman que desde entonces ha sido editado para incorporar dicha llamada.)
Ted Hopp
37

IntentCompat.makeRestartActivityTask

La nueva forma de hacerlo es utilizando IntentCompat.makeRestartActivityTask

Haga una intención que pueda usarse para relanzar la tarea de una aplicación en su estado base. Esto es como makeMainActivity (ComponentName), pero también establece los indicadores Intent.FLAG_ACTIVITY_NEW_TASK y 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
fuente
66
Esto reinicia la tarea, pero no reinicia el proceso, ni siquiera el Applicationobjeto. Por lo tanto, los staticdatos, los datos inicializados durante la creación de las Applicationclases jni permanecen en su estado actual y no se reinicializan.
Ted Hopp
2
@TedHopp Oh, me perdí esa parte. Agregué System.exit (0); Pero no estoy seguro al 100% de que funcionará. Voy a probar que este último sobre
Ilya Gazman
1
La mejor solución sin usar una biblioteca de código abierto para hacerlo. Manos arriba y gracias por proporcionar esta respuesta, +1
blueware
44
Lamentablemente, IntentCompat.makeRestartActivityTaskahora está en desuso . Si inspecciona el código fuente , es tan simple como simplemente agregar las banderas Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK.
Paul Lammertsma
IntentCompat.makeRestartActivityTask eliminado
luckyhandler
28

Hay un buen truco. Mi problema fue que alguna biblioteca jni de C ++ realmente antigua filtró recursos. En algún momento, dejó de funcionar. El usuario intentó salir de la aplicación y volver a iniciarla, sin ningún resultado, porque terminar una actividad no es lo mismo que terminar (o matar) el proceso. (Por cierto, el usuario podría ir a la lista de aplicaciones en ejecución y detenerla desde allí; esto funcionaría, pero los usuarios simplemente no saben cómo finalizar las aplicaciones).

Si desea observar el efecto de esta función, agregue una staticvariable a su actividad e increméntela, por ejemplo, presionando un botón. Si sale de la actividad de la aplicación y luego vuelve a invocarla, esta variable estática mantendrá su valor. (Si la aplicación realmente se cerró, a la variable se le asignaría el valor inicial).

(Y tengo que comentar por qué no quería corregir el error en su lugar. La biblioteca fue escrita hace décadas y filtró recursos desde entonces. La gerencia cree que siempre funcionó . El costo de proporcionar una solución en lugar de una solución ... Creo que entiendes la idea.)

Ahora, ¿cómo podría restablecer una biblioteca compartida jni (también conocida como dinámica, .so) al estado inicial? Elegí reiniciar la aplicación como un nuevo proceso.

El truco es que System.exit () cierra la actividad actual y Android recrea la aplicación con una actividad menos.

Entonces el código es:

/** 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));
    }
}

La actividad de llamada simplemente ejecuta el código MagicAppRestart.doRestart(this);, se ejecuta la actividad de llamada onPause()y luego se vuelve a crear el proceso. Y no olvide mencionar esta actividad en AndroidManifest.xml

La ventaja de este método es que no hay demoras.

UPD: funcionó en Android 2.x, pero en Android 4 algo ha cambiado.

18446744073709551615
fuente
3
utilicé activity.startActivity (i); System.exit (0); solución genio
max4ever
55
Esta solución cierra la aplicación por mí, pero no se reinicia. Al menos en Android 4.3.
Kirill Rakhman
1
En samsung galaxy mega android 4.2.2 causa un bucle infinito de reinicio. Entonces la aplicación no comenzará de nuevo.
Gunhan
@Gunhan 1) ¿qué sucede si reemplazas System.exit(0)por android.os.Process.killProcess(android.os.Process.myPid());? 2) un bucle infinito probablemente significa que no eliminan la actividad superior cuando reinician una aplicación. En principio, puede agregar una variable booleana estática, establecerla en verdadero antes de invocar la actividad de reinicio, y después del reinicio será falsa. Por lo tanto, la actividad puede averiguar si el reinicio ya ha ocurrido o no (y si ha sucedido, simplemente termine () ). OTOH, su informe significa que el truco no funciona de manera idéntica en todos los dispositivos.
18446744073709551615
@Gunham Si está comenzando la misma actividad que está causando el reinicio, entonces será un bucle infinito en cualquier dispositivo.
Lukas Hanacek
23

Mi solución no reinicia el proceso / aplicación. Solo permite que la aplicación "reinicie" la actividad doméstica (y descarte todas las demás actividades). Parece un reinicio para los usuarios, pero el proceso es el mismo. Creo que en algunos casos la gente quiere lograr este efecto, así que lo dejo aquí para su información.

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

Ok, modifiqué mi aplicación y no terminaré A automáticamente. Dejo que esto se ejecute siempre y termine el onActivityResultevento. De esta manera puedo usar las banderas FLAG_ACTIVITY_CLEAR_TOP+ FLAG_ACTIVITY_NEW_TASKpara obtener lo que quiero:

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);
        }
    }
}

y en el 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);
}

¡Gracias de cualquier manera!

Atascado
fuente
23
Esto no reiniciará la aplicación, solo volverá a crear las clases. Por lo tanto, cualquier variable estática dentro de las clases retendrá valores de ejecuciones anteriores.
Brian White
14
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Nirav Ranpara
fuente
24
Esto no reiniciará la aplicación, solo volverá a crear las clases. Por lo tanto, cualquier variable estática dentro de las clases retendrá valores de ejecuciones anteriores.
Brian White
14

El único código que no activó "Su aplicación se ha cerrado inesperadamente" es el siguiente. También es un código no obsoleto que no requiere una biblioteca externa. Tampoco requiere un 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
fuente
8

Descubrí que esto funciona en API 29 y versiones posteriores, con el propósito de matar y reiniciar la aplicación como si el usuario la hubiera lanzado cuando no se estaba ejecutando.

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.
}

Eso se hizo cuando la actividad del iniciador en la aplicación tiene esto:

<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>

He visto comentarios que afirman que se necesita una categoría de DEFAULT, pero no he encontrado que ese sea el caso. He confirmado que el objeto Aplicación en mi aplicación se vuelve a crear, por lo que creo que el proceso realmente se ha eliminado y reiniciado.

El único propósito para el que uso esto es reiniciar la aplicación después de que el usuario haya habilitado o deshabilitado los informes de fallas para Firebase Crashlytics. Según sus documentos, la aplicación debe reiniciarse (proceso finalizado y recreado) para que ese cambio surta efecto.

Mark Peters
fuente
7

La mejor manera de reiniciar completamente una aplicación es reiniciarla, no solo saltar a una actividad con FLAG_ACTIVITY_CLEAR_TOPy FLAG_ACTIVITY_NEW_TASK. Entonces, mi solución es hacerlo desde su aplicación o incluso desde otra aplicación, la única condición es conocer el nombre del paquete de la aplicación (ejemplo: ' 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);
}

Ejemplo de reinicio de uso o lanzamiento de la aplicación A desde la aplicación B :

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

Puede verificar si la aplicación se está ejecutando:

 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 : Sé que esta respuesta está un poco fuera de tema, pero puede ser realmente útil para alguien.

Choletski
fuente
5

Mi mejor manera de reiniciar la aplicación es usar finishAffinity();
Since, solo finishAffinity();se puede usar en versiones JELLY BEAN, por lo que podemos usarlo ActivityCompat.finishAffinity(YourCurrentActivity.this);para versiones inferiores.

Luego, use Intentpara iniciar la primera actividad, de modo que el código se verá así:

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 eso ayude.

Hussein ND
fuente
1
Esto finaliza todas las actividades en la tarea actual, pero no reinicia el proceso, ni siquiera recrea el objeto Aplicación. Por lo tanto, los datos estáticos, los datos inicializados durante la creación de la Aplicación, o por clases jni, permanecen en su estado actual y no se reinicializan.
Ted Hopp
3

Aquí hay un ejemplo para reiniciar su aplicación de manera genérica utilizando PackageManager:

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Alireza Ghanbarinia
fuente
Esto reinicia la tarea, pero no reinicia el proceso, ni siquiera el Applicationobjeto. Por lo tanto, los datos estáticos, los datos inicializados durante la creación de las Applicationclases jni permanecen en su estado actual y no se reinicializan.
Ted Hopp
3

prueba esto:

Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
veeson
fuente
1
Como con cualquier otra respuesta aquí que ya sugiera lo mismo, esto no reiniciará la aplicación, solo volverá a crear las clases. Por lo tanto, los datos estáticos dentro del proceso no se restablecerán.
Ted Hopp
2

Inicie directamente la pantalla inicial con FLAG_ACTIVITY_CLEAR_TASKy FLAG_ACTIVITY_NEW_TASK.

Yijun Li
fuente
2

Tuve que agregar un controlador para retrasar la salida:

 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
fuente
2

Utilizar:

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

Funciona a partir del nivel de API 16 (4.1), creo.

Peter Mortensen
fuente
1

Puedes usar el startInstrumentationmétodo de Activity. Necesita implementar vacío Instrumentationy puntiagudo en manifiesto. Después de eso, puede llamar a este método para reiniciar su aplicación. Me gusta esto:

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);
}

Obtengo el nombre de la clase Instrumentation dinámicamente pero puedes codificarlo. Algo como esto:

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

Llame a startInstrumentationrecargar su aplicación. Lea la descripción de este método. Pero no puede ser seguro si actúa como la aplicación kill.

Enyby
fuente
1

La aplicación en la que estoy trabajando tiene que dar al usuario la posibilidad de elegir qué fragmentos mostrar (los fragmentos se cambian dinámicamente en tiempo de ejecución). La mejor solución para mí fue reiniciar completamente la aplicación.

Así que probé muchas soluciones y ninguna de ellas me ha funcionado, pero esto:

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 eso ayude a alguien más!

hzitoun
fuente
0

prueba esto:

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
fuente
-1

Con la biblioteca Process Phoenix . La actividad que desea relanzar se llama "A".

Sabor de Java

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

Sabor Kotlin

// kotlin
fun restart() {
    ProcessPhoenix.triggerRebirth(context)
}
Raymond Chenon
fuente
Esto tiene el desafortunado resultado de desconectar su depurador.
DrSatan1
-3

Puede reiniciar su actividad actual de esta manera:

Fragmento :

activity?.recreate()

Actividad :

recreate()

fuente
3
Esto no es lo que OP quiere hacer.
Ted Hopp