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


81

在Android应用程序中,如果我们没有正确处理异常,通常会出现“强制关闭”错误。

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

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


5
尝试正确处理异常。自动重新启动的应用程序可能会使用户烦恼。
Tomas Andrle'4

12
如果崩溃,我只想重新启动我的应用程序。我认为这比烦人更友好,尤其是当用户在我的应用程序中时。是的,我正在尝试使每个异常正确。:)
约翰尼(Johnny)2010年

2
@Johnny:请为您的问题分享解决方案。
Code_Life 2012年

查看本文以在出现任何异常时重新启动您的应用程序。
Chintan Rathod 2015年

Answers:


100

为此,您必须做两件事:

  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()方法中显示一个对话框“很抱歉,应用程序崩溃,希望再也没有了:)”。


4
我知道了。现在的问题是在哪里实现uncaughtException方法?请帮助。谢谢。
杰·马尤

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

1
如果您扩展该活动,则值得注意的是,您需要对可用作应用程序入口点的每个活动都做同样的事情(包括Android OS可能决定启动的活动-例如,当窗口关闭时等)
Mick

1
在通过“管理应用”菜单强制停止该过程之后,它似乎在ICS中不起作用。
sunghun

5
YourApplication是什么意思?我使用了@Mahesh建议,但没有成功。请有人解释。
Shervin Gharib

17

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

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

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


1
谢谢你的提示。接下来的问题是何时调用UncaughtExceptionHandler.uncaughtException?如果用户未单击“强制关闭”按钮,是否仍将调用UncaughtExceptionHandler.uncaughtException?
约翰尼,2010年

3
@Johnny当应用程序引发未处理的异常时,您将获得强制关闭。如果使用UncaughtExceptionHandler,则您的应用程序可以处理其所有异常,并且用户将永远不会看到“强制关闭”对话框。换句话说,将在显示“强制关闭”对话框时调用UncaughtExceptionHandler。但是,您将需要小心如何处理应用程序捕获的任何意外的异常。继续并假装什么也没有发生显然是有风险的。
Dave Webb

感谢您的解释。它很好地说明了UncaughtExceptionHandler。但是我看到强制关闭后会自动重新启动的应用程序。例如。启动器(也许不是一个很好的例子,但是我已经看到第三方应用程序也可以这样)。如果我希望我的应用程序像这样工作怎么办?我必须使用某种系统权限吗?
约翰尼,2010年

10

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

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

此代码获取“ Thread.setDefaultUncaughtExceptionHandler”并在关闭后调用..
萨蒂亚,2013年

2

只需在您的包中添加此类

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

在您的应用程序或每个活动类的onCreate()方法内部,然后只需调用:

Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
            SplashScreenActivity.class));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.