Android App Restarts upon Crash/force close
My android app is getting restarted after force close, through my entire application which consist of 20 activities, I am relying on static data created on a main activity. So once the app is getting crashed all my static data is getting lost and when the app auto restarts practically it does not have any essential data to operate upon.
My question is, upon crash i want this things to happen
- If the app crashes, I don't want the app to restart rather I want all the stack/task related with this app to be wiped out of memory. A user can restart it from the beginning again
- If I can't prevent app from restart, at least I want to preserve essential data so that when the app restarts I can assign them back. Also when it restarts I want my app to start from the main activity.
I know when activity crashes android system will bring next activity in stack to foreground, and this is reason for my app producing redundant results. also i went through the android developers but only thing i got to know was setting up an attribute in Manifest android:finishOnTaskLaunch="true"
. But unfortunately this is of no help to me. I would appreciate your help on solving this issue, and also letting me know the cause and analysis.
Solution 1:
Best solution would be instead of using Static data, use
Shared Preferences
or store data in aDatabase
and if anyuncaught Exception
occurs, show a message likeApplication has crashed and a report is sent to the admin
and then restart the Activity that caused the Crash. This way user can continue using the application.Do the same but instead of restarting the Activity which caused the Exception restart the application.
create a class used to handle unCaughtException
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);
}
}
and in every Activity create an Object of this class and set it as the DefaultUncaughtExceptionHandler
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this,
YourCurrentActivity.class));
Solution 2:
public class MyApp extends Application {
private static final String TAG = "MyApp";
private static final String KEY_APP_CRASHED = "KEY_APP_CRASHED";
@Override
public void onCreate() {
super.onCreate();
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread thread, Throwable exception) {
// Save the fact we crashed out.
getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit()
.putBoolean( KEY_APP_CRASHED, true ).apply();
// Chain default exception handler.
if ( defaultHandler != null ) {
defaultHandler.uncaughtException( thread, exception );
}
}
} );
boolean bRestartAfterCrash = getSharedPreferences( TAG , Context.MODE_PRIVATE )
.getBoolean( KEY_APP_CRASHED, false );
if ( bRestartAfterCrash ) {
// Clear crash flag.
getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit()
.putBoolean( KEY_APP_CRASHED, false ).apply();
// Re-launch from root activity with cleared stack.
Intent intent = new Intent( this, MyRootActivity.class );
intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK );
startActivity( intent );
}
}
}