Android: How to auto-restart an application after it has been "force closed"?

Android

Android Problem Overview


In an Android application, we usually got the "Force Closed" error if we didn't handle the exceptions properly.

How can I restart my application automatically if it is force closed?

Is there any specific permission used for this?

Android Solutions


Solution 1 - Android

To accomplish this you have to do two things:

  1. Avoid the "Force close" - standard way of application crash.
  2. Setup a restart mechanism when the crash happens anyway.

See below how to do these:

  1. Call Thread.setDefaultUncaughtExceptionHandler() in order to catch all uncaught exception, in which case uncaughtException() method will be called. "Force close" will not appear and the application will be unresponsive, which is not a quite good thing. In order to restart your application when it crashed you should do the following :

  2. In the onCreate method, in your main activity initialize a PendingIntent member:

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

Then put the following in your uncaughtException() method:

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

You also must call System.exit(), otherwise will not work. In this way your application will restart after 2 seconds.

Eventually you can set some flag in your intent that the application crashed and in your onCreate() method you can show a dialog "I'm sorry, the application crashed, hope never again :)".

Solution 2 - Android

The trick is make sure it doesn't Force Close in the first place.

If you use [the Thread.setDefaultUncaughtExceptionHandler() method][1] you can catch the Exceptions that are causing your application to Force Close.

Have a look [at this question][2] for an example of using an UncaughtExceptionHandler to log the Exceptions raised by an application.

[1]: https://developer.android.com/reference/java/lang/Thread.html#setDefaultUncaughtExceptionHandler(java.lang.Thread.UncaughtExceptionHandler) "Android Documentation" [2]: https://stackoverflow.com/questions/601503/how-do-i-obtain-crash-data-from-my-android-application "How do I obtain crash-data from my Android application?"

Solution 3 - Android

If you use Crittercism or some other error report service, accepted answer is almost right..

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

Solution 4 - Android

Just add this class in your package

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

In your application or in every activity class, inside the onCreate() method then simply call:

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

Solution 5 - Android

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

Solution 6 - Android

Below is the code that worked for me. You should call appInitialization() in onCreate() method of 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);
        }
    };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohnnyView Question on Stackoverflow
Solution 1 - AndroidGyuri MajercsikView Answer on Stackoverflow
Solution 2 - AndroidDave WebbView Answer on Stackoverflow
Solution 3 - AndroidRenetikView Answer on Stackoverflow
Solution 4 - AndroidSuraj VaishnavView Answer on Stackoverflow
Solution 5 - AndroidSatyaView Answer on Stackoverflow
Solution 6 - AndroidManideepView Answer on Stackoverflow