In an app I'm making I have an Object to a class called Preferences in my MainMenu activity. I want to use this object in several pages. In the object is a class which contains an array with numbers. When I use it in another activity (Film) it changes one of the numbers in the object. Then I go back to the main menu and into a new activity (CurrentPrefs) in which I display the array of numbers on the screen. When I displayed the numbers they didn't contain the changes made in the Film file. So I started testing around with the variables a bit.
When I start the MainMenu, which is the start activity, it sets the object. Then when I enter film and check the object it still has the same name (object.toString()). I also checked to make sure that the values where changed correctly which they were.
Next I went back to MainMenu and checked again. The object still had the same name and the value were also like I changed them in Film.
Finally I entered the CurrentPrefs activity and there it goes wrong. The object suddenly has a different name and it also no longer contains the changes I made to it.
Why has the object changed and, more importantly, how can I make sure it doesn't change and stays the same everywhere?
There are any number of reasons why your object's values changed. Perhaps the previous Activity got destroyed and recreated without you realizing it.
You should check out Android's SharedPreference class. It is a way to store, edit, and retrieve preferences and have access to them in any Activity:
http://developer.android.com/reference/android/content/SharedPreferences.html
If you well know activity's lifecycle you can also understand why it happens. Probably some of your operation are delegated to onResume() method which is called whenever activity comes back from onPause() or immediately after onCreate(), while other operations reside in onCreate() called only when activity starts or after onDestroy(). I advise you to control this and trying to move all setText() in onResume() so that every updated object's variable will be read again.
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 ;)
I would like to know if there is a method to Save a Custom Class while rotating in an Android app.
I want to save all instanced object called of the MatrixGame class...someone can help me?
Thanks
Since the Fragment lifecycle is independent - when you're using a Fragment you can set it so it doesn't get destroyed upon configuration changes.
As you noticed, the Activity class gets destroyed and re-created when you rotate the app (or apply other configuration changes), if you want to persist the Activity state you can use sqlite and save whatever you need in the onPause() method. Then in the onCreate() method check the DB for last known state.
If you want to avoid saving the state "forever" (meaning, the user turns off the app and tomorrow when she turns it back on - you want to start fresh and not load the last known state) you can add a timestamp and set a threshold which, if passed, the data is considered stale and gets disregarded.
Two comments:
As #saprvade wrote, Fragments gets destroyed by default, in order to prevent it you should call: setRetainInstance(true)
In case you want to implement #saprvade's other suggestion (have the activity ignore rotation changes) you can see the following explanation of how to implement: https://stackoverflow.com/a/456918/1057429
You should serialize your object. You can implement Parcelable or implement Serializable (Parcelable is several times faster). Then you will be able to put it in a Bundle in onSaveInstanceState and restore it in onCreate or onRestoreInstanceState.
Also, you can serialize your object to String, e.g. json string.
Another option would be to store your object in a database or a file. It depends on your needs.
If you don't want to recreate this object on screen rotation you can change the lifecycle of your Activity by adding a configuration change flag in AndroidManifest.xml. If we are talking about a Fragment, you can call setRetainInstance(true) to avoid fragment recreation on rotation.
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.
I have a tabhost in my first activity and Im calling another activity sometimes; to handle some details. I need to remember the last tab selected in my first activity when the second one returns. Problem is the first activity is getting destroyed and created again and onSaveInstanceState is not getting called. The only option which I can think of is to write the last tab selected to external memory and read it back, which seems a little extreme considering this is just one tag. Is there any other option? I cant avoid the second activity (I had tried to change that to another fragment--fragment calling another fragment-- but that didn't work so well for me)
Cheers
If you want to save small amounts of data in Android, you can always use SharedPreferences. Here is a good example on how to use it.
And there are some other storage options for Android listed here
I have an Activity that has many fields (class fields/members). I want to set these fields by calling other activities (with startActivityForResult) but the field values are not kept. It looks like each time I return from another activity to my original one, a new instance is created and the fields are re-initialised (the onCreate() method is called each time I return from another activity, also onDestroy() is called on the original one each time I load another activity with startActivityForResult; I am never calling finish()). I hope I explained my problem well.
Any suggestions welcome.
Thanks,
Silviu
Make sure all your fields have unique id's as Android uses these id's to retain the field values when it redraws the activity.
Have you set android:launchMode="singleInstance" in the Android Manifest for the Activity where you have the startActivityForResult code?
If so remove that launchMode as it as some known issues with startActivityForResult.