I have an app that consists mostly of one instance that is a tree of objects. Every time my phone sleeps or I switch app my app resets and all the data within this tree of objects is lost.
I first tried using onSaveInstanceState() but the savedinstancestate bundle would not allow me to pass on the instance of the object I needed. I tried to pass the object off as a parcel but the objects within my object could not be saved to the parcel.
Lastly I tried using getNonConfigurationInstance which didn't appears to work and I abandoned getting it to work when I looked up that it was depreciated. The alternative to it is for API11, I am using API7.
Any advice appreciated, I've read the documentation through but cannot find anything short of going through all my objects and saving each variables one by one to save my instance state.
Thanks
You should use getNonConfigurationInstance only in conjunction with onRetainNonConfigurationInstance, because the former retains the object and the latter saves it. Also, they work only for configuration changes — i.e., when activity is immediately recreated in the same process.
If objects on your tree are simple, you can try putting it into a JSON format and then serializing/deserializing it. I have once done that to persist state of my controller hierarchy, worked great.
You can put Bundles inside Bundles with putBundle(String key, Bundle value).
You can put Parcelables inside Bundles with putParcelable(String key, Parcelable value).
Options 2, 3 and 4 will require you to write a recursive converter of your tree into/from either JSONObjects, Bundles or Parcelables.
Related
My app initially makes a request for a list of objects from a server. These objects are currently kept in memory as an ArrayList<MyObject>. However, I want these objects to be passed through multiple activities before the user terminates the flow by pressing a button. I could make the ArrayList serializable and pass it through Intent extras. But I could also store MyObject(s) in a SQLite database and access/modify them in any Activity without having to go though intents. I was wondering what the norm is to accomplish this.
EDIT: forgot to mention that all the values would be deleted once the user terminates the flow.
SQLite is not the best way to go in your case since you don't need the data to be persistent after you close the app. It will just slow your app having to store and retrieve all entries on every activity transition. You can do one of the following instead:
Pass Serializable the way you described. Might be slower than the other alternatives though
Make MyObject implement Parcelable and use [intent.putParcelableArrayListExtra()](https://developer.android.com/reference/android/content/Intent.html#putParcelableArrayListExtra(java.lang.String, java.util.ArrayList))
Extend Application and load the list from the network in your Application.onCreate() and call getList() from activities that need it. That way you load it once and you don't need to pass it between different activities.
I have a class, Savable that serialize the entire class. It was quick easy and great. Unfortunately, this is a problem if I want to update my app. If I make any changes to Saveable, or its descendants, when an instance is deserialized from an older version, there are virtual, and or abstract errors and other errors thrown.
Reading the Android saving data page here, developers are supposed to use one of the ways listed. As I am building an alarm app, I have opted for the SQLLite option.
The problem, until now, my app has been created with my Saveable class in mind. Switching to a database will require a full reworking of my Alarm class because Alarm has other descendants of Saveable in it. Therefore, to save each alarm, I will need a database for every sub-class of Saveable.
Currently, I have a method, Saveable.save(Context context) that serializes the object to fill. This will require a rewrite because now instead of serializing the entire Alarm class, I need to save the core Alarm stuff the Alarm.db, the subclasses of Saveable into subclass.db.
This presents another issue now with loading. I have a method, Saveable.LOAD(File path), which deserializes a Saveable object, that can be cast to it's original class. Now, since the Alarm class contains other Saveable objects that need to be saved in separate DBs, the Alarm class will need a reference to the each sub-saveable class in alarm.
Needless to say, this becomes explosively messy, quickly. I am not opposed to the work (programming is amazing), but before I short change myself again, is this the way you would solve this problem?
I'm a newer programmer, but can't you get a serialization code for updating that allows an object/class to used with an updated version by going into the command line and putting say: serialver class name and it spits out the static final longserialVersionUID. Then make a static final long serialVersionUID = (insert random long number the command line gives here) in the class you want to serialize and then use with an updated version of the program. You probably already know this, and may not be the answer you are looking for, but me being new its the only way I have heard of serializing a class, updating the source code, then deserializing a class and using it with the updated code.
I'm developing an Android app which stores a TreeSet object using serialization in a file. I need to serialize the object on close of my app and deserialize on launch because I need an access during a complete runtime. Unfortunately it's quite unpredictable on which activity the user will start/end so it's unclrear to me where are the right places to put this serialization and deserialization calls so that the object is available during the complete runtime.
thanks in advance for any ideas
Well, depending on how performance dependant your app is and how complex your serialization process is I'd read on startup in your main activities onCreate() and write everytime a value is being set. Simple and unefficient, but safe.
The question is simple, if I make an object parcelable, and put it into a bundle and create a fragment using the bundle. Does the object get cloned or is it referenced.
The context.
I have got an object stored/referenced in an ArrayList. Depending on the type of object in the ArrayList (polymorphism is used). I create a fragment suitable for dealing with it.
I need to also pass this object to the fragment. The fragment is used within a custom view pager. I do not wish to have duplicate objects and it seems to me parcelable clones objects.
Another method is to pass the index of the object in the ArrayList. and then get a reference to the arraylist from the fragment using getActivity().myList.get(Integer passed to ). But it doesn't seem very safe to me (ArrayList contents may change, although I simply delete everything and start again). I have also read, that you should avoid passing arguments to a fragments constructor as it may be recreated using the default no-args constructor.
(Although I'm currently destroying any recreated fragments as there are some strange problem with reattaching to the correct view, another post).
New sub-question: is there a way to pass a value by reference to a fragment?
The question is simple, if I make an object parcelable, and put it into a bundle and create a fragment using the bundle. Does the object get cloned or is it referenced.
It may get cloned, if not immediately, at other points in time (e.g., when the fragment's arguments Bundle is included in the instance state).
I have also read, that you should avoid passing arguments to a fragments constructor as it may be recreated using the default no-args constructor.
Correct.
Another method is to pass the index of the object in the ArrayList. and then get a reference to the arraylist from the fragment using getActivity().myList.get(Integer passed to ). But it doesnt seem very safe to me (ArrayList contents may change, although I simply delete everything and start again).
Don't use an ArrayList. Use a HashMap with a durable key. Pass the key to the fragment. Have the fragment get the data via the key. Make sure anyone deleting this object (and thereby removing it from the HashMap) does so only when this fragment does not exist, or notifies this fragment so it knows how to handle this scenario.
I am creating an app to manage homework, and have a class called Assignment. I wish to add an ArrayList to a bundle, how should I do this?
Is it something to do with serialisable/parsable data, if so, all the data contained within an Assignment is simple data such as Strings and Integers (with the exception of a Course object which also contains simple data types)?
You should use this method Intent.putParcelableArrayListExtra()
Of course the objects of the ArrayList should be parcelables!
Moreover, in case your data is huge, you should not use an intent to "carry them" to another activity. Think of another approach (i.e. a MemoryManager class to handle your data).