Reputation: 521
How do I simply just restart my ENTIRE app instead of trying to worry about saving the instance perfectly in onSaveInstanceState and reinitializing everything perfectly when resumed/restored in onRestoreInstanceState? (this can quickly become error prone)
Upvotes: 0
Views: 2049
Reputation: 3706
How do I simply just restart my app instead of trying to worry about saving the instance
You mean the current activity? Do nothing (Don't implement onSaveInstanceState
and onRestoreInstanceState
).
The activity gets created automatically when changes happen. If there is no saved instance state, the activity won't restore any data.
Edit:
I think I came across similar issue too few weeks earlier, where I've to kill all the activities in the back stack and open a fresh new activity.
// Start Main Activity
Intent intent = new Intent(this, MainActivity.class);
finishAffinity();
startActivity(intent);
Use finishAffinity()
. This works on > API 16.
When you kill all the activities in the back stack and open the main activity, it is kind of similar to restarting your app.
Upvotes: 0
Reputation: 764
Try implementing this way
private final String IS_RE_CREATED = "is_re_created";
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(IS_RE_CREATED, true);
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
if (savedInstanceState.containsKey(IS_RE_CREATED)) {
boolean isRecreated = savedInstanceState.getBoolean(IS_RE_CREATED, false);
if (isRecreated) restartApplication(this);
}
}
public void restartApplication(Context context) {
String packageName = context.getPackageName();
PackageManager packageManager = context.getPackageManager();
// Intent to start launcher activity and closing all previous ones
Intent restartIntent = packageManager.getLaunchIntentForPackage(packageName);
restartIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
restartIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(restartIntent);
// Kill Current Process
Process.killProcess(Process.myPid());
System.exit(0);
}
Note: It is not a recommended to forcefully restart application.
Upvotes: 0
Reputation: 521
UPDATE 10.1.16
I chose to do this in onCreate since onRestoreInstanceState behaves oddly sometimes.
This method is based on the fact that the onCreate(Bundle) is null unless the activity is being revived in which case it is whatever onSaveInstanceState(Bundle) set it to.
I set TWO flags. One in onSaveInstanceState in the Bundle so to know that it is a valid Bundle set by me. The other in the class itself to determine if onCreate was called because of recreation or rotation. And so in onCreate I checked to see if onSaveInstanceState is not null, check the Bundle flag, and check bInit (which defaults to false). If both flags are true then it means android dumped and destroyed our apps memory and the safest way to ensure everything is initialized again in a linear-style application is to just restart it and launch the beginning activity.
public class SomeMiddleActivity extends AppCompatActivity
{
private static boolean bInit = false; // only way it will be false again is if android cleared our memory and we are recreating
@Override
public void onSaveInstanceState(Bundle state)
{
// set a flag so that onCreate knows this is valid
state.putBoolean("StateSaved", true);
super.onSaveInstanceState(state);
}
@Override
protected void onCreate(Bundle savedInstanceState)
{
// this must be called first always for some reason
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
{
if (savedInstanceState.getBoolean("StateSaved", false) && !bInit)
{
// we were recreated... start app over
Intent intent = new Intent(getApplicationContext(), Startup.class);
startActivity(intent);
finish();
return;
}
}
bInit = true; // this will stay true until android has cleared our memory
.......
}
Hope this helps someone and although this has worked thus far, if anyone has a different suggestion let me know.
And FYI: the onSaveInstanceState(Bundle, PersistableBundle) version of onSaveInstanceState is never called ever so I dont know why they even implement it. (?)
REFERENCES:
ACCORDING TO ANDROID DOCUMENTATION
onCreate
Bundle: If the activity is being re-initialized after previously being shut down then this Bundle contains the data it most recently supplied in onSaveInstanceState(Bundle). Note: Otherwise it is null.
Upvotes: 0