user2319927
user2319927

Reputation:

android: Saving activity state

I know this question has been asked many times but i have tried many solutions to no avail. sob sob.

Ill try to keep it simple. Im writing an app that uses spinners and edit texts to intake float numbers. so screen A has 4 spinners and 4 edit texts. I use a next button to open screen B

onClick(){
    a.putExtras(sendScoreSoFar);
    a.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    startActivity(a);
}

Screen B is much the same with 3 spinners and 2 edittexts. I can move from A to B and back to A while preserving the input from the user but when I go back to B again B is reset. I need to preserve the input so the user can flick back and forth to check input. I could use shared preferences but need to reset on the first loadup.

Ive tried various lines in the manifest:

 <activity
        android:name="com.package.Screen2"
        android:label="@string/app_name" 
        android:alwaysRetainTaskState="True"
        android:launchMode="singleInstance">
        >
        <intent-filter>...

and heres my on create and saved instance state code.

@Override
public void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    setContentView(R.layout.screen2);
    super.onCreate(savedInstanceState);
    setUpVariables();
    if (savedInstanceState != null) {
        int a = savedInstanceState.getInt("weightlostorprev");
        spinner1.setSelection(a);
        int b = savedInstanceState.getInt("metricorimp");
        spinner1.setSelection(b);
        int c = savedInstanceState.getInt("acute");
        spinner1.setSelection(c);

        etBigWeight.setText(savedInstanceState.getString("bigweight"));
        etSmallWeight.setText(savedInstanceState.getString("smallweight"));
    }
    gotBasket = getIntent().getExtras();
    passedResults = gotBasket.getFloatArray("the data");
    passedWeight = passedResults[5];
    Toast c1 = Toast.makeText(Screen2.this, "on create run!  new run = "
            + newRun, Toast.LENGTH_LONG);
    c1.show();
    // question.setText(gotBread);
}

//@Override
public void onSaveInstanceState(Bundle savedInstanceState) {
    super.onSaveInstanceState(savedInstanceState);
    // Save UI state changes to the savedInstanceState.
    // This bundle will be passed to onCreate if the process is
    // killed and restarted.
    int a = spinner1.getSelectedItemPosition();
    savedInstanceState.putInt("weightlostorprev", a);
    int b = spinner2.getSelectedItemPosition();
    savedInstanceState.putInt("metricorimp", b);
    int c = spinner1.getSelectedItemPosition();
    savedInstanceState.putInt("acute", c);

    savedInstanceState.putString("bigweight", etBigWeight.getText()
            .toString());
    savedInstanceState.putString("bigweight", etBigWeight.getText()
            .toString());

}

//@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Restore UI state from the savedInstanceState.
    // This bundle has also been passed to onCreate.
    int a = savedInstanceState.getInt("weightlostorprev");
    spinner1.setSelection(a);
    int b = savedInstanceState.getInt("metricorimp");
    spinner1.setSelection(b);
    int c = savedInstanceState.getInt("acute");
    spinner1.setSelection(c);

    etBigWeight.setText(savedInstanceState.getString("bigweight"));
    etSmallWeight.setText(savedInstanceState.getString("smallweight"));
}

I know theres a simple solution, but i cant find it. thanks in advance.

EDIT as far as I can see you cant send data to onResume so although the answers given were correct I solved the problem by removing all shared preferences code, removing the changes to the manifest: android:alwaysRetainTaskState="True" android:launchMode="singleInstance"> and instead of trying to preserve the activity, killing it as normal (with the back button) and just send the values of the spinners and edit texts in a bundle using startactivityforresult. So screenA starts screenB sending bundle a, then when screenB is killed with the back button, it sends bundle b back to screenA, then when screenA now starts screenB it Sends bundles a and b and b is populated with values in bundle b. Probably no one interested but I thought id put up the solution anyway. I can put up the code if anyone wants.
Thanks for the answers guys ill be taking a look at your options next time.

Upvotes: 1

Views: 818

Answers (2)

Craig Heneveld
Craig Heneveld

Reputation: 389

I am assuming you are moving back to A screen via the back button which is finishing your B screen.

You may want to consider putting each screen into a fragment, loading them both in your activity and using the fragment manager to flip between the fragments.

Here are a resources that will pertain to this solution.

Switching between Fragment view

http://www.vogella.com/articles/AndroidFragments/article.html#fragmentspersistence

You can use the fragments lifecycle call backs to handle the data and setRetainInstance() to "Control whether a fragment instance is retained across Activity re-creation (such as from a configuration change)."

If you need pre honeycomb compatibility, check out the support libraries to do so.

Upvotes: 1

Mark Allison
Mark Allison

Reputation: 21909

Your choices are that you either persist the data (using, for example, SharedPreferences as you already know). Alternatively you could create a Service which holds your values. Both Activities bind to the Service, and can get and set the values from the Service. The Service will stay alive across your Activity transition, so the values set by ActivityA will be available to ActivityB.

Saving Activity state will only persist the state to the same Activity type. It is used when resuming an Activity, or persisting state across, for example, an orientation change.

Upvotes: 0

Related Questions