La aplicación de Android se reinicia al cerrar / cerrar fuerza

Mi aplicación para Android se está reiniciando después de cerrar la fuerza, a través de toda mi aplicación que consta de 20 actividades, estoy confiando en los datos estáticos creados en una actividad principal. Así que una vez que la aplicación se está estrellando todos mis datos estáticos se está perdiendo y cuando la aplicación automática se reinicia prácticamente no tiene ningún dato esencial para operar.

Mi pregunta es, cuando accidente quiero que estas cosas sucedan

  1. Si la aplicación se bloquea, no quiero que la aplicación se reinicie. Quiero que toda la pila / tarea relacionada con esta aplicación se borre de memoria. Un usuario puede reiniciarlo desde el principio otra vez
  2. Si no puedo evitar que la aplicación reinicie, al menos quiero conservar los datos esenciales para que cuando la aplicación se reinicie, pueda asignarlos de nuevo. Además, cuando se reinicie, quiero que mi aplicación empiece con la actividad principal.

Sé que cuando la actividad bloquea el sistema androide traerá la siguiente actividad en la pila a primer plano, y esta es la razón de mi aplicación que produce resultados redundantes. También pasé por los desarrolladores de Android, pero lo único que llegué a saber fue la creación de un atributo en Manifest android:finishOnTaskLaunch="true" . Pero desafortunadamente esto no es de ayuda para mí. Agradecería su ayuda en resolver este problema, y ​​también me dejó saber la causa y el análisis.

  1. La mejor solución sería en lugar de usar datos estáticos, usar Shared Preferences o almacenar datos en una Database y si alguna uncaught Exception produce, mostrar un mensaje como la Application has crashed and a report is sent to the admin y luego reiniciar la Actividad que causó el Crash . De esta manera el usuario puede seguir utilizando la aplicación.

  2. Haga lo mismo, pero en lugar de reiniciar la actividad que provocó la excepción, reinicie la aplicación.

Crear una clase usada para manejar unCaughtException

 public class MyExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler { private final Context myContext; private final Class<?> myActivityClass; public MyExceptionHandler(Context context, Class<?> c) { myContext = context; myActivityClass = c; } public void uncaughtException(Thread thread, Throwable exception) { StringWriter stackTrace = new StringWriter(); exception.printStackTrace(new PrintWriter(stackTrace)); System.err.println(stackTrace);// You can use LogCat too Intent intent = new Intent(myContext, myActivityClass); String s = stackTrace.toString(); //you can use this String to know what caused the exception and in which Activity intent.putExtra("uncaughtException", "Exception is: " + stackTrace.toString()); intent.putExtra("stacktrace", s); myContext.startActivity(intent); //for restarting the Activity Process.killProcess(Process.myPid()); System.exit(0); } } 

Y en cada actividad crear un objeto de esta clase y establecerlo como el DefaultUncaughtExceptionHandler

  Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this, YourCurrentActivity.class)); 
 public class MyApp extends Application { private static final String TAG = "MyApp"; private static final String KEY_APP_CRASHED = "KEY_APP_CRASHED"; @Override public void onCreate() { super.onCreate(); final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable exception) { // Save the fact we crashed out. getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit() .putBoolean( KEY_APP_CRASHED, true ).apply(); // Chain default exception handler. if ( defaultHandler != null ) { defaultHandler.uncaughtException( thread, exception ); } } } ); boolean bRestartAfterCrash = getSharedPreferences( TAG , Context.MODE_PRIVATE ) .getBoolean( KEY_APP_CRASHED, false ); if ( bRestartAfterCrash ) { // Clear crash flag. getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit() .putBoolean( KEY_APP_CRASHED, false ).apply(); // Re-launch from root activity with cleared stack. Intent intent = new Intent( this, MyRootActivity.class ); intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity( intent ); } } } 
  setContentView(R.layout.current); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); } code.... 

(Referencia: Archie.bpgc)

Si el usuario está deteniendo la aplicación (desde Configuración> Aplicaciones> Información de la aplicación, o desde la lista de aplicaciones recientes) o si el sistema operativo está deteniendo la aplicación, puede guardar lo que necesite con onSaveInstanceState() .

Sin embargo, si su aplicación se está estrellando, entonces no hay mucho que pueda hacer al respecto (aparte de guardar cosas importantes periódicamente en las preferencias / bases de datos / etc.). Es probablemente mejor centrarse en la prevención de accidentes, en lugar de tratar de manejar los accidentes!

No almacenar datos en campos estáticos. Su proceso podría ser detenido en un evento de memoria baja y se perderá todo. Sus actividades se restaurarán del estado guardado si el usuario cambia a su aplicación de nuevo, pero sus variables estáticas no se restaurarán.

Bueno, una aplicación no es sólo interfaz (actividades). Imagine que tiene alguna aplicación empresarial compleja, utilizando transacciones SQL, seguridad, autenticación web, etc. Es casi imposible hacer que cada actividad sea capaz de recuperar todo el contexto de la aplicación usando sólo las preferencias compartidas. Así que en este caso, yo uso este pedazo de Código:

 public class MyApplication extends Application { private static final String TAG = "my.app"; public static final String MainActivityName = "my.app.top.activity"; @Override public void onCreate() { try{ ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); ComponentName componentInfo = taskInfo.get(0).topActivity; if (MainActivityName.length()>0 && !componentInfo.getClassName().equals(MainActivityName)){ Log.d(TAG, "Partial Restart Not Supported! : " +componentInfo.getClassName()); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); return; }else Log.d(TAG, "!!! BCSApplication topActivity=" +componentInfo.getClassName()); }catch(Exception eee){} super.onCreate(); /* .... */ } /* .... */ } 

Mi aplicación también se reanudaba con pantalla en blanco, cuando se estaba cayendo. Para resolver esto, he comprobado el objeto savedInstanceState en onCreate método de mi actividad principal y si no es nulo (significa que es reiniciado por el sistema android), entonces terminé mi actividad. Algo como eso:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { finish(); } } 

Puede ayudar en su caso también.

  • Cómo agrupar las notificaciones de Android como whatsapp?
  • Razones por las que mi aplicación Android se bloquea en mi teléfono de forma consistente, pero no en mi emulador
  • Restaurar la pila posterior de Android después de cerrar la aplicación
  • 17.8 MiB asignación de montón para un simple "Hello World" proyecto?
  • Diferenciar entre un inicio de actividad de la pantalla de inicio o de otra actividad de la aplicación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.