Before I begin, I have read this, this and some more articles online. I am still unable to find a right way to do it.
So I have just one activity in my App, and 6 fragments. First one is a ListFragment which loads a list from a SQLite table. When user taps on a row in this list, I do 2 things:
1) Get an int from that row through a listener, and pass it back to the parent activity which stores it as a class variable using a simple setter method.
2) Replace this ListFragment with another simple Fragment. This new Fragment uses a simple getter() on that class variable to retrieve some information from a different table, and show all the details to the user.
So far so good. Now if I am on this details Fragment, and I change the screen orientation, the activity state is not reloaded (as I am checking if savedInstanceState is null in the onCreate()), but however, the class variables lose their value, and my app crashes.
Basically I am trying to pass data from the ListFragment to the details Fragment. I am doing it through the activity, which is causing a problem. As per Android Documentation:
All Fragment-to-Fragment communication is done through the associated
Activity. Two Fragments should never communicate directly.
There is no specific code which is giving me trouble, so didn't post any.
The onSaveInstanceState and onRestoreInstanceState is only used to save and restore per-instance state of an activity in case your activity is destroyed by OS (for example, to free the memory or in order to recreate it when the device orientation was changed). So you can save your variable in onSaveInstanceState and get them back using onRestoreInstanceState.
For your next question, I think this article will help you. Also answer by Gene for this question will help you.
Related
I have a form activity every Edittext open another activity when I change data and I get it in my activity I lose the others that I have changed them before . this is initial state and this is what I get by changing any data.
You need a consistent data model in which to store those values. If it's size isn't larger than 2MB you can make this model Parcelable and seriali. After that you must cache those values either in savedInstanceState, SharedPrefs, singleton (I do not recommend it), or local DB (i.e. sqlite). After doing so, whenever your activity is displayed you should check if you already have a saved value for that field and fill it with that.
you can fix this by letting it open another fragment instead of activity and make sure that you dont destroy the activity.
so overall view you gonna have 1 main activity and each edit text will replace fragment view
Bonjour Flora
An activity is not supposed to be persisted if not displayed. That means it could stay as you left in when returning from another activity but it also may not.
If the system needs to free memory it will destroy the activity and recreate it when the user gets back to it. This is the expected behaviour on Android.
So what you should do is store your data when the activity goes out (in onPause() method) and fill your edittexts when the activity goes back in (in onResume() method)
Pay also attention that you need to handle what they call configuration change (such as screen rotation) using onConfigurationChanged() that allows you to pass some information between the former configuration and the latter for reuse.
Finally you should build your layout according to Android's guidelines (material design) for your UI to look a bit more conventional ;)
Hello Everyone,
I had do a search on activity retain state.So I am getting to options/solutions for that:-
Using savedInstanceState() and retainInstanceState() methods.
Using Parent Child hierarchy declare in manifest and its working.
(Example Url:-How can I return to a parent activity correctly? I had same problem mention in Note scetion of the answer.That case is match with my problem.
So,I want to retain the activity states just like Whats app(call/chats/contacts fragments).
But In My scenario,I am fetching the contacts from server.So how can I persist my data while switching between chat and my fragment activity?
So while timing to fetch new data of my contact list from server.I want to save ui of my listview/recyclerview with old data previously I had.
Also suggest which method is good from above two methods or need to implement in other way.
This is a practice I've been using for a while now, but it seem to be deprecated, the literature seems to say that the correct way to save and restore data when the screen goes to the background or rotates is fragments.
I would like your opinion on this
What I've been doing in my apps is create a class I call ApplicationDataHolder()
This has all the variables that define the state of each activity and fragment stored in it.
For example I have an activity that shows a list of tickets and two widgets one for the way to sort the tickets and one to select if it will be ascending or descending.
For this I have created the variables List _tickets, SortOrder _order and boolean _ascending in my DataHolder() and given them default values
Whenever the activity is recreated/created for the first time, I access those variables to set default values (what the default sort order will be, what the initial list will be)
Is this not the optimal way? could this cause problems (for example after the screen has rotated too many times) what is the benefit of using fragments or saveinstancestate/restoreinstancestate over this?
Thanks in advance for any help you can provide
the correct way to save and restore data when the screen goes to the
background or rotates is fragments
Here they are talking about data that is obtained dynamically, either as input data from the user or data coming from a sensor or web-service. This data needs to be restored using onSaveInstanceState() and onConfigurationChanged() when a state change occurs, such as rotation or a tab swipe.
Initial values can of course be saved in a central global constants file, nothing wrong with that.
First, I'd to state that I've been searching for a solution for this problem for three days now, that may means either I'm not asking the right question or not using a good approach. If any, please guide me in the right direction.
This is the scenario: I've an Activity and a bound Service. The Service holds some data and processes it as necessary while posting a persistent (ongoing) notification with some information. The Activity has three Fragments inside a ViewPager that displays the data processed by the Service.
The Fragments are a List Fragment, that shows the active data entries available, a Details Fragment that displays the details for each data and a Parameters Fragment where the user can modify how the data is processed.
[Service] <-> ([Activity] -> [ViewPager([List], [Details], [Parameters])])
Everything works just fine. My Activity binds to the Service, the ViewPager is created after and then the Fragments fetch information trough an Interface.
Here comes the fun part... Screen Rotation!
As the Service binds asynchronously, when the user rotates the screen the Fragments no longer have the data because the Activity is bounding the service while they're already present and not recreated thanks to the ViewPager.
I've been trying to figure this out but it seems that I don't have the knowledge to solve it. I've tried making static references to the fragments, setting them up before the service is rebound but I can't get a stable solution.
I'd be using android:configChanges in my manifest but there are different layouts for each orientation.
Again, if I'm using a bad approach, please, guide me!
Difficult to suggest when I don't know your code but thinking out loud....
Can you have a "worker fragment" that is never displayed (i.e headless) and has setRetainInstance(true) set so it does not lose any state you have set.
Your worker fragment would bind to the service instead of the activity and maintain a reference to it.
If you need to communicate with your Activity, you can do this with callbacks.
Your other fragments could communicate with the worker instead of the Activity.
This process would basically make the activity little more than a shell into which the rest of your components are hosted. Rotation would lose nothing because all data is held in the retained fragment.
During the screen rotation process the activity is completely destroyed and use of android:congfigChange is discouraged. but what you can do is you can override saveInstanceState(bundle) method in which you can save the data present in your activity at the time it is destroyed by the system in response to the screen rotation. and later receive it as the system passes the bundle to the activities onCreate(bundle) method or get it from the restoreInstanceState(Bundle) method.
I have an ViewPager with 4 fragments,
at the last fragment I want to make a validation and save the values that was inserted in the previous fragments.
I tried to override the onSaveInstanceState and save a Bunble with the data but the method not getting a call (only when the screen goes off).
How can I save the data and access it from the parent activity?
I think given your requirements you would be better to pass a model object from the Activity to the each of the fragments in turn. Each of the fragment's would store the data required in the model, and the once the last fragment is complete, it can be validated.
As a side note, I believe onSaveInstanceState is used for storing the current state of a Activity / Fragment so that it can be reinitalised without having to call possible long running background tasks rather than a way to share data.