2010-04-21 127 views
65

在Android应用程序中,如果我们没有得到正确的例外,我们通常会得到“强制关闭”错误。Android:如何在“强制关闭”后自动重启应用程序?

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

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

+4

试着获得正确的例外。自动重新启动的应用程序可能会让用户烦恼。 – 2010-04-21 09:17:44

+10

我只是想重新启动我的应用程序,如果它坠毁。我认为这比烦人更友好,特别是当用户在我的应用程序中时。 是的,我试图让每个例外都正确。 :) – Johnny 2010-04-21 09:47:56

+2

@Johnny:请为你的问题分享解决方案。 – 2012-07-02 14:29:38

回答

90

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

  1. 避免“强制关闭” - 应用程序崩溃的标准方式。
  2. 无论如何,当崩溃发生时设置重启机制。

见下文如何做这些:

  1. 呼叫Thread.setDefaultUncaughtExceptionHandler()为了捕获所有未捕获的异常,在这种情况下uncaughtException()方法将被调用。 “强制关闭”不会出现,应用程序将无响应,这不是一件好事。 为了重新启动应用程序时坠毁,你应该做到以下几点:

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

    Intent intent = PendingIntent.getActivity(
        YourApplication.getInstance().getBaseContext(), 
        0, 
        new Intent(getIntent()), 
        getIntent().getFlags()); 
    

然后把下面的您uncaughtException()方法:

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

您还必须调用System.exit() ,否则将无法正常工作。 通过这种方式,您的应用程序将在2秒后重新启动。

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

+3

我明白了。现在的问题是在哪里实现uncaughtException方法? plz帮助。谢谢。 – 2011-11-04 05:38:36

+1

@MayuMayooresan您可以扩展应用程序类或Activity并在onCreate()中执行以下操作: Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler(){...}); – AgentKnopf 2012-04-04 07:50:35

+1

如果您扩展了活动,值得注意的是您需要为每个可以充当应用程序入口点的活动(包括Android OS可能决定启动的活动 - 例如窗口死亡等)执行相同的操作 – Mick 2012-05-31 19:47:18

15

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

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

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

+1

感谢您的线索。 后续问题是何时调用UncaughtExceptionHandler.uncaughtException? 如果用户没有点击“强制关闭”按钮,UncaughtExceptionHandler.uncaughtException仍会被调用吗? – Johnny 2010-04-21 09:46:34

+3

@Johnny当应用程序引发一个未处理的异常时,您会收到强制关闭。如果使用UncaughtExceptionHandler,则应用程序可以处理其所有异常,并且用户永远不会看到强制关闭对话框。换句话说,当强制关闭对话框被显示时,UncaughtExceptionHandler被调用。但是,您将需要小心如何处理应用程序捕获的任何意外异常;继续和假装什么都没发生显然是有风险的。 – 2010-04-21 10:08:10

+0

感谢您的解释。它很好地解释了UncaughtExceptionHandler。 但我见过的应用程序会在强制关闭后自动重启。例如。启动器(可能不是一个好例子,但我看到第三方应用程序也是这样工作的)。如果我想让我的应用程序像这样工作会怎样?我必须使用某种系统权限吗? – Johnny 2010-04-21 15:13:22

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

过于详细,不清楚。 – greg7gkb 2013-02-01 03:39:30

+0

此代码获取“Thread.setDefaultUncaughtExceptionHandler”并在关闭后调用。 – Satya 2013-02-28 07:10:33

6

如果使用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); 
      } 
}); 
0

只是在你的包添加该类

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)); 
相关问题