En una aplicación de Android, normalmente aparece el error "Forzar cierre" si no gestionamos las excepciones correctamente.
¿Cómo puedo reiniciar mi aplicación automáticamente si se cierra a la fuerza?
¿Se utiliza algún permiso específico para esto?
En una aplicación de Android, normalmente aparece el error "Forzar cierre" si no gestionamos las excepciones correctamente.
¿Cómo puedo reiniciar mi aplicación automáticamente si se cierra a la fuerza?
¿Se utiliza algún permiso específico para esto?
Respuestas:
Para lograr esto tienes que hacer dos cosas:
Vea a continuación cómo hacer esto:
Llame Thread.setDefaultUncaughtExceptionHandler()para capturar todas las excepciones no detectadas, en cuyo caso uncaughtException()se llamará al método. "Forzar cierre" no aparecerá y la aplicación dejará de responder, lo cual no es nada bueno. Para reiniciar su aplicación cuando se bloqueó, debe hacer lo siguiente:
En el onCreatemétodo, en su actividad principal, inicialice un PendingIntentmiembro:
Intent intent = PendingIntent.getActivity(
YourApplication.getInstance().getBaseContext(),
0,
new Intent(getIntent()),
getIntent().getFlags());
Luego ponga lo siguiente en su uncaughtException()método:
AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
System.exit(2);
También debes llamar 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 bloquee y en su onCreate()método puede mostrar un cuadro de diálogo "Lo siento, la aplicación se bloqueó, espero que nunca más :)".
El truco es asegurarse de que no fuerce el cierre en primer lugar.
Si usa el Thread.setDefaultUncaughtExceptionHandler()método , puede detectar las Excepciones que están causando que su aplicación se cierre por la fuerza.
Eche un vistazo a esta pregunta para ver un ejemplo del uso de un UncaughtExceptionHandlerpara registrar las excepciones generadas por una aplicación.
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);
}
});
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();
}
Simplemente agregue esta clase en su 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);
}}
En su aplicación o en cada clase de actividad, dentro del método onCreate (), simplemente llame a:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
SplashScreenActivity.class));