pie - Android: ¿Cómo reiniciar automáticamente la aplicación después de haber sido "forzada a cerrar"?
android pie (5)
En una aplicación de Android, usualmente recibimos el error "Force Closed" si no recibimos las excepciones correctas.
¿Cómo puedo reiniciar mi aplicación automáticamente si se cierra forzosamente?
¿Hay algún permiso específico para esto?
El truco es asegurarse de que no forzar Cerrar en primer lugar.
Si usa el método Thread.setDefaultUncaughtExceptionHandler()
, puede capturar las Excepciones que están causando que su aplicación se cierre Thread.setDefaultUncaughtExceptionHandler()
.
Eche un vistazo a esta pregunta para ver un ejemplo del uso de UncaughtExceptionHandler
para registrar las Excepciones planteadas por una aplicación.
Para lograr esto, debes hacer dos cosas:
- Evite el "cierre forzado": forma estándar de bloqueo de la aplicación.
- Configure un mecanismo de reinicio cuando ocurra el bloqueo de todos modos.
Vea a continuación cómo hacer esto:
Llame a
Thread.setDefaultUncaughtExceptionHandler()
para capturar todas las excepciones no detectadas, en cuyo caso se llamará al métodouncaughtException()
. "Force close" no aparecerá y la aplicación no responderá, lo cual no es algo bastante bueno. Para reiniciar su aplicación cuando falló, debe hacer lo siguiente:En el método
onCreate
, en su actividad principal, inicialice un miembroPendingIntent
:Intent intent = PendingIntent.getActivity( YourApplication.getInstance().getBaseContext(), 0, new Intent(getIntent()), getIntent().getFlags());
A continuación, coloque lo siguiente en su método uncaughtException()
:
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
System.exit(2);
También debe llamar a System.exit()
; de lo contrario, no funcionará. De esta forma, su aplicación se reiniciará después de 2 segundos.
Eventualmente puede establecer alguna bandera en su intento de que la aplicación se onCreate()
y en su método onCreate()
puede mostrar un diálogo "Lo siento, la aplicación se colgó, espero nunca más :)".
Si usa Crittercism o algún otro servicio de informe de errores, la respuesta aceptada es casi correcta.
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
public void uncaughtException(Thread thread, Throwable ex) {
Intent launchIntent = new Intent(activity().getIntent());
PendingIntent pending = PendingIntent.getActivity(CSApplication.getContext(), 0,
launchIntent, activity().getIntent().getFlags());
getAlarmManager().set(AlarmManager.RTC, System.currentTimeMillis() + 2000, pending);
defaultHandler.uncaughtException(thread, ex);
}
});
Solo agrega esta clase en tu paquete
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);
}}
Entonces simplemente llame:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
SplashScreenActivity.class));
public class ForceCloseExceptionHandalingActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
setContentView(MyLayout());
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
myHandaling(paramThread, paramThrowable);
}
});
}
private ViewGroup MyLayout(){
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
Button btnHello =new Button(this);
btnHello.setText("Show all button");
btnHello.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
setContentView(MyLayout2());
}
});
mainLayout.addView(btnHello);
return mainLayout;
}
private ViewGroup MyLayout2(){
LinearLayout mainLayout = new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
Button btnHello =new Button(this);
btnHello.setText("I am a EEROR uncaughtException");
btnHello.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Log.e("Alert","btn uncaughtException::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException222",Toast.LENGTH_LONG).show();
View buttone = null;
setContentView(buttone);
}
});
Button btnHello2 =new Button(this);
btnHello2.setText("I am a EEROR Try n catch");
btnHello2.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
try{
View buttone = null;
setContentView(buttone);
}
catch (Exception e) {
Log.e("Alert","Try n catch:::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert Try n catch",Toast.LENGTH_LONG).show();
setContentView(MyLayout());
}
}
});
mainLayout.addView(btnHello);
mainLayout.addView(btnHello2);
return mainLayout;
}
public void myHandaling(Thread paramThread, Throwable paramThrowable){
Log.e("Alert","Lets See if it Works !!!" +"paramThread:::" +paramThread +"paramThrowable:::" +paramThrowable);
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException111",Toast.LENGTH_LONG).show();
Intent in =new Intent(ForceCloseExceptionHandalingActivity.this,com.satya.ForceCloseExceptionHandaling.ForceCloseExceptionHandalingActivity.class);
startActivity(in);
finish();
android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
protected void onDestroy() {
Log.e("Alert","onDestroy:::");
Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert onDestroy",Toast.LENGTH_LONG).show();
super.onDestroy();
}