How to pull string from bundle in onResume()? - android

I have an activity that is resumed after a user picks a contact. Now before the user picks a contact onSavedInstanceState is called and i put a string in the Bundle. Now, After the user selects the contact and the results are returned. onRestoreInstanceState doesnt get called. only onResume() gets called. So how would i go about pulling my string back out of the bundle once the activity is resumed?

Lets say you have two Activities A and B, and Activity A starts Activity B. If you want to pass information from A to B, you can pass information from A to B with:
Intent i = new Intent(this. ActivityB.class);
i.putExtra("Key","Value");
startActivity(i);
Then in Activity B you can get the string with
String value = this.getIntent().getExtras().getString("keyName");
However, if you want to pass information from B to A you have to use a different method. Instead of using startActivity you need to use startActivityForResult. A description of this method is found here: How to return a result (startActivityForResult) from a TabHost Activity?

First, why onRestoreInstanceState isn't firing: According to the documentation, onRestoreInstanceState gets called after onStart(), which, according to the activity lifecycle diagram, only gets called after onCreate or onRestart. If your main activity isn't destroyed when the user goes to choose a contact, then onStart will never fire, and onRestoreInstanceState will never fire. The diagram shows this to be the case when "Another activity comes in front of the activity", and onPause is fired - From there your Activity will only be killed if the system needs more memory.
Second, how to get the data you saved before choosing a contact- A local variable should do it, since the activity is staying in memory. If you get to a point where the activity does not stay in memory, onRestoreInstanceState should fire.

Related

Can onSaveInstanceState(...) be used when switching between activities?

I do have 2 activities A (contains a button that redirects to A and a text input) and B (contains a button the redirects to A) and I was trying to switch from one to another but also to keep the text value from A.
I was trying to save the text value in a Bundle using onSaveInstanceState(...) but it simply didn't work.
Here are the steps I do:
(on A) add some text
in A, implement onSaveInstanceState(...) and save the value of text in Bundle
(on B) click the button that points back to A
(on A) the stored value is gone (also the Bundle sent to onCreate(...) is null)
To my surprise when I'm in A and change the orientation the value is stored (and the Bundle sent to onCreate(...) is not null)
Did I miss something?
In short, no.
onSaveInstanceState is meant to save the instance state during things like:
Memory pressure
Screen rotation
Whenever the system decides to stop the activity and resume it later (e.g. it moves to the background, get's forgotten by the user, and later is being picked up again).
Further reading is available here.
You should store those values you want to keep in SharedPreferences, for example during your onPause call.
No you can not use onSaveInstanceState() while switching between activities.
onSaveInstanceState() Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle) (the Bundle populated by this method will be passed to both).
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).
You can get more idea on Android Developer pages:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)

Activity lifecycle: what to do when work is done in a child activity?

There are plenty of questions about activity lifecycle, but I couldn't find the suitable one.
I have an Activity (named A) which shows the cars from one user. Internally, the activity stores userId into a variable to load user's cars in the list. userId comes from previous activity.
When user presses the 'new car' button on A, Activity B is launched. User fills the car's form and presses save. User's new car is persisted to database.
At this point, which method must be called to return to activity A from B?
Should I call finish()? Then, user returns to A and B is destroyed. But, what happens if A was destroyed before? How can A be restored if userId is not present?
Maybe calling startActivity(A) with userId as intent extra? But then, I'm creating a new activity!
Other options?
I'm sure somebody would help to clarify these concepts. :)
Edit:
See comments of accepted answer for more information.
finish should be called to return.
1) if A was destroyed it will be recreated by android, unless you called finish() on it. If you saved its state properly there shouldn't be a problem at all.
2) This would just move Activity A back to the top of the Stack or creting a new Activity, depending on what flags you add to the intent.
3) I'd use startActivityForResult in Activity A to start B and then let the user enter the values, put set the result in B and call finish().

Saving the instance of an Activity to reuse it

I have an Activity A with a button on it which when clicked navigates to Activity B. Now from this Activity B when the back button is pressed i get back to Activity A which is quite obvious. But once again when i click on the button on Activity A a new instance of Activity B is launched.
My query: Is there a way so that when i press the back button on Activity B it's instance is stored and so when i again click the button on Activity A the saved instance of B is launched instead of a new one.
Hoping for a solution..
if you don't want to pass data.. or just want to go back on Previous activity
finish() in onClick
http://developer.android.com/reference/android/app/Activity.html
In addition, the method onSaveInstanceState(Bundle) is called before placing the activity in such a background state, allowing you to save away any dynamic instance state in your activity into the given Bundle, to be later received in onCreate(Bundle) if the activity needs to be re-created.
To think that it won't be easy to deal with it. The activity in the android can be store but you cannot call the android system to using that instance of your when you navigate to the activity B.
Read this link http://developer.android.com/reference/android/app/Activity.html
it give all information that you can do with it but not all as you want.
When you navigate from activity B to activity A the android itself has been store your activity B's instance temporarily in the memory and that instance will destroy completely anytime later. If you navigate it from A to B again, then the instance of Activity B will be reuse again if it still exist in the memory otherwise it recreate the activity again. In any case the activity B is reuse or recreate, the method onCreate is always call (all method in Lifecycle like onResume ...etc) then all data of your activity B is now new data that's not your old data before you navigate it to the activity A. This is what android system doing so that you cannot launch activity B without calling those method.
if you want the activity B look like the same as before navigate to activity A you should probably saving the necessary data in the method onPause() on the activity B then set those data back to the component of activity B when it call onCreate(). The method onSaveInstanceState(Bundle) should not be use in this case because the android os version which is before honeycomb (3.0) is not invoked that method.
This could be difficult to deal if you are working with online data or listview, webview ...etc and also save data by your own it could the risk to your application itself.
Anyway I hope this could be some help to you.

Task, Back Button, and onSaveInstanceSate method

Hello I am just a little confused after reading these materials on Tasks and Back Stack, Android Developer Guide:
It says:
When Activity A starts Activity B, Activity A is stopped, but the system retains its state (such as scroll position and text entered into forms). If the user presses the Back button while in Activity B, Activity A resumes with its state restored.
While in the APIs reference for onSaveInstanceState() method, it says:
One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it.
The above two situations seem identical to me ("press the Back button to Activity A" and "navigate back from Activity B to Activity A"). But I don't understand why while the former says Activity A resumes with its previous state restored while the latter says the particular instance of Activity B will never be restored. Any explanations?
Thanks in advance!
I think the first one is saying that A will be saved so it can be restored, and the second one is saying that B will not be saved because it can't be restored.

How to handle activity coming to foreground again

The books I have are abysmal at explaining how to work with the lifecycle, there's a lot I'm missing that I'm hoping somebody can fill in.
My app structure is that when it's first started, it starts an activity full of legalbabble that the user has to accept. When he says 'ok', I start my main activity and then I call finish like this:
public void onClick(View view) { //as a result of "I accept"
Intent mainIntent = new Intent(mParent, EtMain.class);
startActivity(mainIntent); // Start the main program
finish();
}
Then in EtMain in the onCreate method, I've got some tabs and I instantiate some classes:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
SetupTabs.setMyTabs(mTabHost, this);
mComData = new ComFields(this); // Create the objects
mDepWx = new WxFields(this, DepArr.Departure);
mArrWx = new WxFields(this, DepArr.Arrival);
mDepVs = new DepFields(this);
mArrVs = new ArrFields(this);
mTabHost.setOnTabChangedListener(new OnTabChangeListener(){
}
Questions:
The 'finish' in the first fragment should terminate the legalbabble activity so it'll never be restarted, right? And the EtMain one will remain forever (until killed externally), even if my app gets pushed to the background, right?
The way it is now, when EtMain gets pushed and later brought to the foreground (by tapping on the icon), it goes through the legalbabble screen as though it's a complete start - that's what I'd like to prevent - going thru the legalbabble screen again.
It would seem that I'd want to override onRestart in the second code fragment and put something in there to restart the app, right? That's the part I'm unclear about.
My question then is what needs to be done in onRestart. Do I have to recreate all the tabs and data in the tabs and all my object instantiations? Or is the memory state of the app saved someplace and then is restored back to the state that it was in before something else was brought to the foreground in which case not much needs to be done because all the objects and listeners will still be there?
Yes after the first activity has ended you shouldn't have to view that activity again. You could also write to the shared preferences that the user has previously seen legal info.
If you're UI object creation is in the onCreate method, this should only be called once. Pausing or resuming will not call the onCreate method again.
Unless you explicitly remove your objects and tabChangedListeners in the onPause method, you should not have to touch them in the onRestart method.
Correct, the state of the app is saved automatically. You shouldn't have to touch the onRestart method.
Hope this helps!
I think the problem is that the launch activity in your manifest is the legalbabble activity, so when you click on the icon, the system launches another one. A better architecture would be to launch the legalbabble activity it from your EtMain activity in the onCreate method of the latter, using startActivityForResult. From the docs:
As a special case, if you call startActivityForResult() with a requestCode >= 0 during the initial onCreate(Bundle savedInstanceState)/onResume() of your activity, then your window will not be displayed until a result is returned back from the started activity.
When you get the result in onActivityResult, you can call finish() if the legal stuff was declined; otherwise everything will proceed normally.
This avoids the problem that the launch activity defined in your manifest finishes when the legal stuff is accepted.
EtMain will not remain forever, if the user backs out (by pressing the BACK key) the Activity will be finished (onPause, then onStop, then onDestroy will be called).
In general you can ignore onRestore until you are doing something complicated.
Once the user has exited your application and re-enters (or presses the icon on the Homescreen), onCreate (followed by onStart and onResume) will be called for your first activity, so you do not need any logic in onRestart, your code in onCreate will do the setting up for you as it did the first time. Because of this your legal babble will appear again when the user starts the app after exiting unless you store a preference (in SharedPreferences or a database or file) to indicate you have already displayed it - in which case finish it straight away and start the main activity.
onRestart is only called when the application goes from the stopped state (onStop has been called but not onDestroy) to the started state (onStart is called but onResume has not yet).
For saving data - some components save their state automatically (e.g. EditTexts remember the text in them, TabHosts remember the currently selected tab etc). Some components will not. If you wish to save extra data then make use of onSaveInstanceState and onRestoreInstanceState. You should only use these methods to restore the state of your application or temporary data, not important things, e.g. the id of the resource what the user was looking at, what zoom level they were at etc. For things like contacts or actual data you should commit these changes to a database, SharedPreferences or other permanent storage (e.g. file) when onPause is called.
I recommend taking a look at the Android Activity lifecycle if you are confused. Or ask more questions!

Categories

Resources