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

时间:2010-04-21 09:01:36

标签: android

在Android应用程序中,如果我们没有得到正确的例外,我们通常会收到“强制关闭”错误。

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

是否有任何特定的权限用于此?

6 个答案:

答案 0 :(得分:93)

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

  1. 避免“强制关闭” - 应用程序崩溃的标准方式。
  2. 无论如何都会在发生崩溃时设置重启机制。
  3. 请参阅以下内容:

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

    2. onCreate方法中,在您的主要活动中初始化PendingIntent成员:

      Intent intent = PendingIntent.getActivity(
          YourApplication.getInstance().getBaseContext(),
          0,
          new Intent(getIntent()),
          getIntent().getFlags());
      
    3. 然后在您的uncaughtException()方法中添加以下内容:

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

      您还必须致电System.exit(),否则将无效。 这样,您的应用程序将在2秒后重新启动。

      最终,您可以在应用程序崩溃的意图中设置一些标记,并在onCreate()方法中显示对话框“对不起,应用程序崩溃了,希望永远不会再次:)”。

答案 1 :(得分:17)

诀窍是确保它首先不会强制关闭。

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

查看at this question,了解使用UncaughtExceptionHandler记录应用程序引发的异常的示例。

答案 2 :(得分:8)

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

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);
            }
});

答案 3 :(得分:2)

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();  
    }

答案 4 :(得分:1)

只需在包中添加此类

即可
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);
}}

然后简单地致电:

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

答案 5 :(得分:0)

以下是对我有用的代码。您应该在 appInitialization()

onCreate() 方法中调用 MainActivity
    /*
    * App Restart on crash logic
    * */

    public void triggerRestart(Activity context) {
        Intent intent = new Intent(context, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
        if (context instanceof Activity) {
            finish();
        }
        Runtime.getRuntime().exit(0);
    }

    private void appInitialization() {
        defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
        Thread.setDefaultUncaughtExceptionHandler(_unCaughtExceptionHandler);
    }

    //make crash report on ex.stackreport
    private Thread.UncaughtExceptionHandler defaultUEH;
    // handler listener
    private Thread.UncaughtExceptionHandler _unCaughtExceptionHandler = new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            // You can code here to send crash analytics
            ex.printStackTrace();
            triggerRestart(currentActivity);
        }
    };