Pregunta ¿Cómo forzar programáticamente un reinicio completo de la aplicación? p.ej. matar, luego comenzar


Tengo una aplicación que incluye tanto un servicio complejo como una IU de actividad. La aplicación se ejecuta en múltiples dispositivos que se comunican entre sí a través de WIFI a través del servicio.

Como la aplicación es un prototipo / en desarrollo, quiero agregar soporte para un "reinicio forzado" que matará a la aplicación y la relanzará. Hay muchas cosas de UI compartidas que se han engomado dependiendo del caso de uso, y sería más fácil durante la prueba (tengo varios dispositivos) si pudiera simplemente tocar un botón para reiniciar la aplicación por completo.

Entonces, ¿alguien tiene alguna sugerencia sobre cómo:

1) Forzar cerrar / detener / matar su propia aplicación, desde dentro de su aplicación.

2) Establezca un temporizador / intento que le indique al SO que inicie su aplicación antes de cerrarla / detenerla / matarla.

¡Cualquier consejo sería apreciado! Gracias.


5
2017-07-22 18:51


origen


Respuestas:


Usa el siguiente código para reiniciar la aplicación:

            Intent mStartActivity = new Intent(HomeActivity.this, SplashScreen.class);
            int mPendingIntentId = 123456;
            PendingIntent mPendingIntent = PendingIntent.getActivity(HomeActivity.this, mPendingIntentId, mStartActivity,
                    PendingIntent.FLAG_CANCEL_CURRENT);
            AlarmManager mgr = (AlarmManager) HomeActivity.this.getSystemService(Context.ALARM_SERVICE);
            mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
            System.exit(0);

7
2018-03-04 14:01



Como puedes imaginar, termina () es lo que quieres usar para matar una actividad. El modo A.C.R. funcionaría, sin embargo, solo reiniciará su actividad, no matará realmente el proceso y lo iniciará de nuevo. Si eso es lo que estás buscando, en lugar de tener una actividad ficticia que reinicie tu actividad original, la forma correcta de hacerlo sería usar banderas.

Intent i = new Intent(this, WrapperActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);

Esas banderas borrarán tu back stack hasta la primera instancia de la Actividad que estés creando, la matará y luego creará una nueva. Esto es esencialmente lo que hace el ejemplo de A.C.R., pero es mucho más conciso.

Si esto no es lo suficientemente bueno para usted, para hacer esto correctamente, es bastante trabajo y requiere un conocimiento más avanzado del sistema Android. Desea crear un servicio que se ejecute en segundo plano (tendrá que ser un proceso separado si desea que se elimine el estado del nivel de la aplicación) que podría iniciar cuando deseara eliminar la aplicación, hacer que la aplicación se matara a sí misma o tener el servicio mata la aplicación por usted, y luego hace que el servicio lance una intención que inicie su actividad / aplicación de respaldo.

¡Espero que esto ayude! ¡La mejor de las suertes!


2
2017-07-22 21:33



Pruebe el siguiente código para reiniciar la aplicación.

Intent i = getBaseContext().getPackageManager()
             .getLaunchIntentForPackage(getBaseContext().getPackageName());
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);

1
2017-10-18 07:20



No se puede hacer. El sistema operativo decide cuándo matar una aplicación. Tu aplicación puede volver a la vida si estaba realmente muerta o simplemente escondida.

Esto es inconveniente, pero la plataforma funciona así. Puede producir el mismo efecto de usuario al administrar sus actividades, lo que poder matar y restaurar


0
2017-07-22 19:00



Puede haber una manera más oficial de hacer esto, pero así es como lo lograría.

Por ejemplo, voy a pretender que solo hay dos actividades, la que se encuentra actualmente (la llamaré FirstActivity) y otra actividad de "ayuda" (llamaré a SecondActivity).

En el primero (del que desea reiniciarlo), tendrá un botón que inicia el reinicio de la aplicación.

restartButton.setOnClickListener(new OnClickListener(){
        @Override
        onClick(View v){
          //when clicked it starts the helper activity and closes the one you're in
          startActivity(new Intent(this, SecondActivity.class));
          finish(); //or you could use FirstActivity.onDestroy(); if you want it completely dead
        }
});

Segunda actividad: todo el propósito es que básicamente puedes reiniciar tu aplicación desde tu aplicación (cierra todo lo demás y luego reinícialo)

Class SecondActivity extends Activity{
        @Override
        onCreate(Bundle savedInstanceState){
                ...
                //it restarts the old activity so it's new and ends this one
                startActivity(new Intent(this, FirstActivity.class));
                finish(); //or you could use SecondActivity.onDestroy(); if you want it
        }

}

Eso reiniciará completamente la primera actividad. No estoy seguro de si será tan completo como desea, pero realmente no hay otra manera de hacer este tipo de cosas AFAIK.


0
2017-07-22 19:07



Aquí está lo que tú necesitas hacer:

  1. Crea un servicio pegajoso
  2. Mata a la aplicación con proceso de matanza llamar desde el Servicio
  3. El servicio fijo se reiniciará y podrá abrir su aplicación con un getLaunchIntentForPackage intención

Me gusta usar un controlador para hacer esto fuera del hilo principal de la interfaz de usuario:

private void scheduleForceClose() {
    final Handler closeAppHandler = new Handler();
            closeAppHandler.post(new Runnable() {
                @Override public void run() {   
                 prefs.edit().putBoolean(StringConstants.FORCE_CLOSED_APP, true).commit();                        
                        Log.i(TAG, "Gonna force kill the app process completely!");
                        System.exit(0);
             android.os.Process.killProcess(android.os.Process.myPid());                        
                }
            });

}

private void scheduleForceOpen() {
    final Handler openAppHandler = new Handler();
    taskOpenApp = new TimerTask() {
        @Override public void run() {
            openAppHandler.post(new Runnable() {
                @SuppressLint("ApplySharedPref") @Override public void run() {
                    Intent intent = getPackageManager().getLaunchIntentForPackage("com.company.yourpackagename");
                    // Reset the force-close flag so that the close timer can begin again                
                    prefs.edit().putBoolean(StringConstants.FORCE_CLOSED_APP, false).commit();
                    startActivity(intent);
                }
            });
        }
    };

    // Decide whether we already force-closed the app, so that we don't repeat it
    boolean alreadyForceClosed = prefs.getBoolean(StringConstants.FORCE_CLOSED_APP, false);
    if (alreadyForceClosed) {
        Log.i(TAG, "App process has already been killed, so schedule app relaunch.");
        Timer timerOpen = new Timer();
        timerOpen.schedule(taskOpenApp, 5000 /* reopen the app after 5 sec */);
    }
}

0
2018-01-17 14:44