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

Android: How to auto-restart application after it's been “force closed”?

在一个Android应用程序中,如果我们没有得到正确的异常,通常会出现"强制关闭"错误。

如果应用程序强制关闭,如何自动重新启动?

是否使用了任何特定的权限?


要做到这一点,你必须做两件事:

  • 避免"强制关闭"——应用程序崩溃的标准方式。
  • 在崩溃发生时设置重新启动机制。
  • 请参见下面的操作方法:

  • 调用Thread.setDefaultUncaughtExceptionHandler()以捕获所有未捕获的异常,在这种情况下,将调用uncaughtException()方法。""强制关闭"不会出现,应用程序将没有响应,这不是一件好事。要在应用程序崩溃时重新启动应用程序,应执行以下操作:

  • onCreate方法中,在主活动中初始化PendingIntent成员:

    1
    2
    3
    4
    5
    Intent intent = PendingIntent.getActivity(
        YourApplication.getInstance().getBaseContext(),
        0,
        new Intent(getIntent()),
        getIntent().getFlags());
  • 然后在您的uncaughtException()方法中输入以下内容:

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

    你也必须打电话给System.exit(),否则就不工作了。这样,应用程序将在2秒后重新启动。

    最后,您可以在应用程序崩溃的意图中设置一些标志,在您的onCreate()方法中,您可以显示一个对话框:"对不起,应用程序崩溃了,希望永远不会再发生了:)"。


    诀窍是确保它不会在第一时间强行关闭。

    如果使用Thread.setDefaultUncaughtExceptionHandler()方法,则可以捕获导致应用程序强制关闭的异常。

    请看这个问题,以获取使用UncaughtExceptionHandler记录应用程序引发的异常的示例。


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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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);
                }
    });

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    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();  
        }


    只需将这个类添加到包中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    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);
    }}

    然后简单地打电话:

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