Android:如何在应用程序被“强制关闭”后自动重启?

zzzyeukh  于 2024-01-04  发布在  Android
关注(0)|答案(8)|浏览(457)

在Android应用程序中,如果我们没有正确处理异常,我们通常会得到“强制关闭”错误。
如果我的应用程序被强制关闭,我如何自动重新启动它?
是否有特定的权限用于此?

vfwfrxfs

vfwfrxfs1#

要做到这一点,你必须做两件事:
1.避免“强制关闭”-应用程序崩溃的标准方式。
1.设置一个重新启动机制,当崩溃发生时,无论如何。
下面看看如何做到这一点:
1.调用Thread.setDefaultUncaughtExceptionHandler()以捕获所有未捕获的异常,在这种情况下,将调用uncaughtException()方法。“强制关闭”不会出现,应用程序将没有响应,这不是一件好事。为了在应用程序崩溃时重新启动应用程序,您应该执行以下操作:
1.在onCreate方法中,在主Activity中初始化PendingIntent成员:

  1. Intent intent = PendingIntent.getActivity(
  2. YourApplication.getInstance().getBaseContext(),
  3. 0,
  4. new Intent(getIntent()),
  5. getIntent().getFlags());

字符串
然后将以下内容放入uncaughtException()方法中:

  1. AlarmManager mgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
  2. mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 2000, intent);
  3. System.exit(2);


您还必须调用System.exit(),否则将无法工作。这样您的应用程序将在2秒后重新启动。
最后,你可以在Intent中设置一些标志,表明应用程序崩溃了,在onCreate()方法中,你可以显示一个对话框“I'm sorry,the application crashed,hope never again:)"。

展开查看全部
e7arh2l6

e7arh2l62#

诀窍是首先确保它不会强制关闭。
如果使用Thread.setDefaultUncaughtExceptionHandler()方法,则可以捕获导致应用程序强制关闭的错误。
查看at this question,了解使用UncaughtExceptionHandler记录应用程序引发的错误的示例。

mu0hgdu0

mu0hgdu03#

如果您使用Crittercism或其他错误报告服务,接受的答案几乎是正确的。

  1. final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
  2. Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
  3. public void uncaughtException(Thread thread, Throwable ex) {
  4. Intent launchIntent = new Intent(activity().getIntent());
  5. PendingIntent pending = PendingIntent.getActivity(CSApplication.getContext(), 0,
  6. launchIntent, activity().getIntent().getFlags());
  7. getAlarmManager().set(AlarmManager.RTC, System.currentTimeMillis() + 2000, pending);
  8. defaultHandler.uncaughtException(thread, ex);
  9. }
  10. });

字符串

ut6juiuv

ut6juiuv4#

只需将此类添加到包中即可

  1. public class MyExceptionHandler implements
  2. java.lang.Thread.UncaughtExceptionHandler {
  3. private final Context myContext;
  4. private final Class<?> myActivityClass;
  5. public MyExceptionHandler(Context context, Class<?> c) {
  6. myContext = context;
  7. myActivityClass = c;
  8. }
  9. public void uncaughtException(Thread thread, Throwable exception) {
  10. StringWriter stackTrace = new StringWriter();
  11. exception.printStackTrace(new PrintWriter(stackTrace));
  12. System.err.println(stackTrace);// You can use LogCat too
  13. Intent intent = new Intent(myContext, myActivityClass);
  14. String s = stackTrace.toString();
  15. //you can use this String to know what caused the exception and in which Activity
  16. intent.putExtra("uncaughtException", "Exception is: " + stackTrace.toString());
  17. intent.putExtra("stacktrace", s);
  18. myContext.startActivity(intent);
  19. //for restarting the Activity
  20. Process.killProcess(Process.myPid());
  21. System.exit(0);
  22. }}

字符串
在您的应用程序或每个Activity类中,在onCreate()方法中只需调用:

  1. Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
  2. SplashScreenActivity.class));

展开查看全部
nsc4cvqm

nsc4cvqm5#

  1. public class ForceCloseExceptionHandalingActivity extends Activity {
  2. /** Called when the activity is first created. */
  3. @Override
  4. public void onCreate(Bundle savedInstanceState) {
  5. super.onCreate(savedInstanceState);
  6. setContentView(R.layout.main);
  7. setContentView(MyLayout());
  8. Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
  9. @Override
  10. public void uncaughtException(Thread paramThread, Throwable paramThrowable) {
  11. myHandaling(paramThread, paramThrowable);
  12. }
  13. });
  14. }
  15. private ViewGroup MyLayout(){
  16. LinearLayout mainLayout = new LinearLayout(this);
  17. mainLayout.setOrientation(LinearLayout.VERTICAL);
  18. Button btnHello =new Button(this);
  19. btnHello.setText("Show all button");
  20. btnHello.setOnClickListener(new OnClickListener() {
  21. @Override
  22. public void onClick(View v) {
  23. setContentView(MyLayout2());
  24. }
  25. });
  26. mainLayout.addView(btnHello);
  27. return mainLayout;
  28. }
  29. private ViewGroup MyLayout2(){
  30. LinearLayout mainLayout = new LinearLayout(this);
  31. mainLayout.setOrientation(LinearLayout.VERTICAL);
  32. Button btnHello =new Button(this);
  33. btnHello.setText("I am a EEROR uncaughtException");
  34. btnHello.setOnClickListener(new OnClickListener() {
  35. @Override
  36. public void onClick(View v) {
  37. Log.e("Alert","btn uncaughtException::");
  38. Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException222",Toast.LENGTH_LONG).show();
  39. View buttone = null;
  40. setContentView(buttone);
  41. }
  42. });
  43. Button btnHello2 =new Button(this);
  44. btnHello2.setText("I am a EEROR Try n catch");
  45. btnHello2.setOnClickListener(new OnClickListener() {
  46. @Override
  47. public void onClick(View v) {
  48. try{
  49. View buttone = null;
  50. setContentView(buttone);
  51. }
  52. catch (Exception e) {
  53. Log.e("Alert","Try n catch:::");
  54. Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert Try n catch",Toast.LENGTH_LONG).show();
  55. setContentView(MyLayout());
  56. }
  57. }
  58. });
  59. mainLayout.addView(btnHello);
  60. mainLayout.addView(btnHello2);
  61. return mainLayout;
  62. }
  63. public void myHandaling(Thread paramThread, Throwable paramThrowable){
  64. Log.e("Alert","Lets See if it Works !!!" +"paramThread:::" +paramThread +"paramThrowable:::" +paramThrowable);
  65. Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert uncaughtException111",Toast.LENGTH_LONG).show();
  66. Intent in =new Intent(ForceCloseExceptionHandalingActivity.this,com.satya.ForceCloseExceptionHandaling.ForceCloseExceptionHandalingActivity.class);
  67. startActivity(in);
  68. finish();
  69. android.os.Process.killProcess(android.os.Process.myPid());
  70. }
  71. @Override
  72. protected void onDestroy() {
  73. Log.e("Alert","onDestroy:::");
  74. Toast.makeText(ForceCloseExceptionHandalingActivity.this, "Alert onDestroy",Toast.LENGTH_LONG).show();
  75. super.onDestroy();
  76. }

字符串

展开查看全部
vdgimpew

vdgimpew6#

下面是我的代码,你应该在MainActivityonCreate()方法中调用appInitialization()

  1. /*
  2. * App Restart on crash logic
  3. * */
  4. public void triggerRestart(Activity context) {
  5. Intent intent = new Intent(context, MainActivity.class);
  6. intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
  7. context.startActivity(intent);
  8. if (context instanceof Activity) {
  9. finish();
  10. }
  11. Runtime.getRuntime().exit(0);
  12. }
  13. private void appInitialization() {
  14. defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
  15. Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
  16. }
  17. //make crash report on ex.stackreport
  18. private Thread.UncaughtExceptionHandler defaultUEH;
  19. // handler listener
  20. private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
  21. @Override
  22. public void uncaughtException(Thread thread, Throwable ex) {
  23. // You can code here to send crash analytics
  24. ex.printStackTrace();
  25. triggerRestart(currentActivity);
  26. }
  27. };

字符串

展开查看全部
lo8azlld

lo8azlld7#

对于Kotlin用户,在MainActivity的onCreate()方法中调用这两个扩展扩展函数,就在超级调用之后,最好在通常在onCreate()中编写的任何其他代码之前。

  1. fun Activity.handleUncaughtException() {
  2. Thread.setDefaultUncaughtExceptionHandler { _, throwable ->
  3. // here you can report the throwable exception to Sentry or Crashlytics or whatever crash reporting service you're using, otherwise you may set the throwable variable to _ if it'll remain unused
  4. val intent = Intent(this, MainActivity::class.java).apply {
  5. putExtra("isCrashed", true)
  6. addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK)
  7. }
  8. startActivity(intent)
  9. finish()
  10. Process.killProcess(Process.myPid())
  11. exitProcess(2)
  12. }
  13. }
  14. fun Activity.showUncaughtExceptionDialog() {
  15. if (intent.getBooleanExtra("isCrashed", false)) {
  16. AlertDialog.Builder(this).apply {
  17. setTitle("Something went wrong.")
  18. setMessage("Something went wrong.\nWe'll work on fixing it.")
  19. setPositiveButton("OK") { _, _ -> }
  20. }.show()
  21. }
  22. }

字符串
我们称之为过程。(Process.myPid())和exitProcess(2),因为如果我们看看Android的开源代码,that's actually the default and proper handling that gets called by Thread. getDefaultUncaughtExceptionHandler(),它会导致我们的应用程序崩溃,并引发臭名昭著的ANR对话框,我们希望通过遵循原始实现而不是在uncaughtException()结束时做任何时髦的事情来成为好的Android公民,比如根本不崩溃或显示另一个活动(永远不要这样做)。
请注意,Kotlin的exitProcess()方法只是Java的System.exit()的 Package 器,无论您在构造函数中传递什么状态代码都无关紧要,我在代码中将其设置为2
请注意,在Intent中,我们将一个布尔标志“isCrashed”设置为true,我们将使用它来检测是否有意外异常导致应用重新启动,并相应地向用户显示一个对话框,通知他们崩溃。
showUncaughtExceptionDialog()扩展函数是可选的,但是如果由于崩溃而要重新启动应用程序,最好通知用户。

展开查看全部
lvjbypge

lvjbypge8#

您可以使用app_watchdogd.sh观看并重新启动您的应用程序与root Android设备

相关问题