2

I have an activity that was passed a value in an intent. I'll call it activity A. Activity A's job is to show a list. From A, I added a menu option to start activity B, whose job it is to hold the form to fill out a new list item. I use an intent to create activity B, which works just fine.

My issue is, when the user navigates back to activity A, I lose the value that was initially passed in via my intent.

[EDIT]: As I've come to learn, I didn't mean back in the previous sentence, I meant UP. See bottom of my post for more.

In activity A, I tried putting the following code, though savedinstanceState is null in onCreate when I navigate back from activity B.

To create activity B, I tried startActivity and startActivityForResult, and in activity B, I use the default back button on the top left to close the activity.

[EDIT]: As I've come to learn, I didn't mean back in the previous sentence, I meant UP. See bottom of my post for more.

How do I store the value of item ID in activity A when I need to come back from Activity B?

EDIT: Full code of Activity A:

public class ActivitiesActivity extends ActionBarActivity {

    public long item_id;

    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putLong(Global.itemIdKey, item_id);
        super.onSaveInstanceState(savedInstanceState);
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState) {
        // Always call the superclass so it can restore the view hierarchy
        super.onRestoreInstanceState(savedInstanceState);

        item_id = savedInstanceState.getLong(Global.itemIdKey);

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (savedInstanceState != null) {
            item_id = savedInstanceState.getLong(Global.itemIdKey);
        }
        else {
            item_id = getIntent().getLongExtra(Global.itemIdKey, item_id);
        }

        setContentView(R.layout.activity_activities);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        ActivitiesActivityFragment frag =
                (ActivitiesActivityFragment) getFragmentManager().findFragmentById(R.id.activitiesFragment);

        frag.setSkillId(item_id);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_activities, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_addactivity)
        {

            Intent intent = new Intent(this, ActivityAdd.class);
            startActivityForResult(intent, 0);

            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

Full code of activity B - I use a fragment here that's empty. Right now I'm just using the native back button to navigate back up to activity A, but I've also tried calling finish() explicitly from a button.

public class ActivityAdd extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_activity_add);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

}

EDIT: Thanks for the answers below. Initially, I implemented shared preferences, though when reading further, I mistakenly said I was navigating BACK from activity B, which this was not the case - I was navigating UP from activity B, which behaves differently from BACK. UP was creating a new instance of Activity A rather than returning to the existing instance until I added

android:launchMode="singleTop"

in my activity declaration in my manifest. I found this in this answer.

Community
  • 1
  • 1
tarun713
  • 2,177
  • 3
  • 17
  • 31
  • you could persist values in shared preferences or you could simply pass values back in as you return to Activity A and then process it onActivityResult() – Nishant Srivastava Dec 21 '15 at 01:44
  • Gotcha, thanks. So I need to use startActivityForResult and listen for the result? I'm surprised there's not a better way to do this, as doing it this way seems to make the child activities be tightly coupled with the parent activity. – tarun713 Dec 21 '15 at 01:51
  • the better way is using the savedInstanceState bundle, but it all depends on how you are saving the data.The savedInstanceState internally saves data as a shared pref only via Bundle. I gave you a workaround which would work. You should debug your app to handle things. – Nishant Srivastava Dec 21 '15 at 01:54
  • Right, that's my question - my savedInstanceState in onCreate is coming back as null, and when I debug, I do see my onSaveInstanceState being called. So I must be doing something wrong where I'm not receiving it again in onCreate. – tarun713 Dec 21 '15 at 01:55
  • 1
    Is your activity A being recreated? Because when you call the activity B, the activity A is not killed. It obviously means that the onCreate() is not going to be called again when you close the Activity B. – Geraldo Neto Dec 21 '15 at 02:11
  • onCreate is being called when I close activity B - I have a breakpoint in it, and it does get called. Here's the flow - I select my menu item. onSaveInstanceState is called, then activity B is visible. when I hit the back arrow on activity B, activity A's oncreate is called - but the savedInstanceState bundle is null. – tarun713 Dec 21 '15 at 02:28

2 Answers2

1

If i am not wrong then you need to implement the onRestoreInstanceState() function in your activity

public void onRestoreInstanceState(Bundle savedInstanceState) {
 // Always call the superclass so it can restore the view hierarchy
 super.onRestoreInstanceState(savedInstanceState);

 // Restore state members from saved instance
 item_id = = savedInstanceState. getLong("ITEM_ID");
}

Reference Link

Nishant Srivastava
  • 4,723
  • 2
  • 24
  • 35
  • Clarification: I can only get onRestoreInstanceState to be invoked when I rotate the device, not when I navigate back from activity B. – tarun713 Dec 21 '15 at 02:20
  • Help me understand this : you want an activity to start , you want to interact with it ..and when you press back you want to read data back in the 1st activity ? In that case the best case would be that you save your id in a private shared preference and read the value back in your onCreate from the same file. You dont need to save states nor do you need onActivityResult. You need to save data not states – Nishant Srivastava Dec 21 '15 at 02:29
  • Yep, I understand that is likely the way I'll have to go. You are spot on - I am still just wondering why my savedInstanceState variable is null in onCreate - I suppose it's because activity A gets completely destroyed when activity B is created, but that still surprises me a bit. I suppose I'm also asking for confirmation that I've implemented saving state properly and it's acting properly. – tarun713 Dec 21 '15 at 02:36
  • Here is the thing onSaveInstanceState () and onRestoreInstanceState() get called only when the activity gets destroyed and is recreated. Check my reference link for the flow diagram. If you didnot save anything in , you will eventually get null . However i still believe there is something wrong in your implementation , if I were you i would always lookup the android docs. – Nishant Srivastava Dec 21 '15 at 02:40
  • you might also wanna look at intents , using which you dont have to worry about sharedpreferences. http://stackoverflow.com/a/2091482/2745762 – Nishant Srivastava Dec 21 '15 at 02:42
  • Thanks. I'm passing activity A its initial value by using an intent - I just didn't want activity B to start activity A - I wanted closing activity B to return to the already created activity - which to me means I need to use finish(), not an intent to create activity A from activity B. – tarun713 Dec 21 '15 at 02:46
  • Well in this case use an intent to start Activity B and return an intent from it and receive it in the onActivityResult inside activity A. This would be the easiest implementation. – Nishant Srivastava Dec 21 '15 at 02:49
1

I recomend you to use SharedPreferences.

If I didn't missunderstood what you were trying to tell to us is you want to save the values of your ListView, it could be done very easy with SharedPerferences.

Store ListView data on SharedPreferences

SharedPreferences prefs=this.getSharedPreferences(0,Context.MODE_PRIVATE);
Editor edit=prefs.edit();
Set<String> SetString = new HashSet<String>();
SetString .addAll(ArrayListName);
edit.putStringSet("ListActivityA", SetString );
edit.commit();

Then when you go back to the Activity A you can retrieve the data doing this :

Set<String> SetString = prefs.getStringSet("ListActivityA", null);
List<String> ListA =new ArrayList<String>(SetString );

Other way to do it, could be done as Radix said, using the onRestoreInstanceState() function.

Test to add a finish() once you start the ActivityB as follows :

Intent intent = new Intent(this, ActivityAdd.class);
startActivityForResult(intent, 0);
finish();
Skizo-ozᴉʞS ツ
  • 19,464
  • 18
  • 81
  • 148
  • I will try to use SharedPreferences. What's confusing me though is why my bundle is null in onCreate. When I put on onRestoreInstanceState it wasn't even called - I read that this function is only called when android destroys an activity due to low resources. I think the proper way to do this is figure out what's wrong with bundle, and why it's coming back null – tarun713 Dec 21 '15 at 02:10
  • Can you post the full code of your ActivityA and ActivityB? If you don't call finish(); when you go to ActivityB once when you press back it won't enter in your `onCreate()` you know that, right? – Skizo-ozᴉʞS ツ Dec 21 '15 at 02:11
  • By the way why you using startActivityForResult instead of startActivity(intent);? – Skizo-ozᴉʞS ツ Dec 21 '15 at 02:21
  • I tried both. They both behave the same. I don't need a result, so I'll change back to startActivity. If I put finish(); where you suggest, that'll actually finish activity A, not B. – tarun713 Dec 21 '15 at 02:26
  • You want that when you are on activityB and you press back it returns to A, right? If you finish the activity A and you have saved the values on sharedpreferences or wherever if you want tou can override the onbackpressed of activityb making an intent to recreate de activityA again and show the info – Skizo-ozᴉʞS ツ Dec 21 '15 at 02:29
  • @Skizo : His implementation contradicts his idea. I am sure he only wants to persist data between jumping form one activity to another and back. He doesnot need to finish() his activity nor save their states for he is not dealing with viewsids here. – Nishant Srivastava Dec 21 '15 at 02:31
  • I get what you are saying here - if I get no value in the intent, default to the value in SharedPreferences. This makes sense. I was just trying to understand why my savedInstanceState is null in this case, and I think I need to read up more on the activity lifecycle to see when that savedInstanceState gets destroyed. Thank you both for your help! – tarun713 Dec 21 '15 at 02:43
  • The thing is if you are on activitya and you go to b automatically the activity a will call on pause and onstop event once is returned to A it will call the onresume event so if you want you can touch stuff of onresume – Skizo-ozᴉʞS ツ Dec 21 '15 at 02:46