zdanman
zdanman

Reputation: 521

Restarting app without worrying about onSaveInstanceState

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

Answers (3)

Srikar Reddy
Srikar Reddy

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

Rishabh Dutt Sharma
Rishabh Dutt Sharma

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

zdanman
zdanman

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

Related Questions