W aplikacji na Androida zwykle otrzymywaliśmy błąd „Wymuś zamknięcie”, jeśli nie obsłużyliśmy poprawnie wyjątków.
Jak mogę automatycznie ponownie uruchomić moją aplikację, jeśli zostanie wymuszona?
Czy zastosowano w tym celu jakieś specjalne pozwolenie?
Odpowiedzi:
Aby to osiągnąć, musisz zrobić dwie rzeczy:
Zobacz poniżej, jak to zrobić:
Wywołaj
Thread.setDefaultUncaughtExceptionHandler()
, aby złapać wszystkie nieprzechwycone wyjątki, w którym to przypadkuuncaughtException()
zostanie wywołana metoda. „Wymuś zamknięcie” nie pojawi się, a aplikacja nie będzie odpowiadać, co nie jest całkiem dobrą rzeczą. Aby ponownie uruchomić aplikację po awarii, wykonaj następujące czynności:W
onCreate
metodzie w głównym działaniu zainicjujPendingIntent
członka:Intent intent = PendingIntent.getActivity( YourApplication.getInstance().getBaseContext(), 0, new Intent(getIntent()), getIntent().getFlags());
Następnie umieść następujące w swojej
uncaughtException()
metodzie:AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE); mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent); System.exit(2);
Musisz też zadzwonić
System.exit()
, inaczej nie zadziała. W ten sposób Twoja aplikacja uruchomi się ponownie po 2 sekundach.W końcu możesz ustawić flagę w zamiarze, że aplikacja się zawiesiła, aw Twojej
onCreate()
metodzie możesz wyświetlić okno dialogowe „Przepraszam, aplikacja się zawiesiła, mam nadzieję, że nigdy więcej :)”.źródło
Sztuczka polega na tym, aby przede wszystkim nie wymusić zamknięcia.
Jeśli korzystasz z
Thread.setDefaultUncaughtExceptionHandler()
metody , możesz wychwycić wyjątki, które powodują wymuszenie zamknięcia aplikacji.Spójrz na to pytanie, aby zapoznać się z przykładem użycia narzędzia
UncaughtExceptionHandler
do rejestrowania wyjątków zgłoszonych przez aplikację.źródło
Jeśli korzystasz z Crittercism lub innej usługi raportowania błędów, zaakceptowana odpowiedź jest prawie poprawna.
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); } });
źródło
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(); }
źródło
Po prostu dodaj tę klasę do swojego pakietu
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); }}
W aplikacji lub w każdej klasie aktywności, wewnątrz metody onCreate (), po prostu wywołaj:
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this, SplashScreenActivity.class));
źródło