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 casouncaughtException()
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
onCreate
método, en su actividad principal, inicialice unPendingIntent
miembro: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 :)".fuente
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
UncaughtExceptionHandler
para registrar las excepciones generadas por una aplicación.fuente
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); } });
fuente
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(); }
fuente
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));
fuente