I have an arraylist of abstract objects(animals) and I'm trying to send and restore this array. The problem is that I need to give a creator when rebuilding the array, at this moment I'm passing a string that I check in the Animal creator and check what kind of animal I need to create.
I don't thing this is the most effective, so is there a better way to create a parcelable abstract array?
Here is a little demo project that describes the problem.
https://github.com/Evertvandenbruel/parcelable-abstract/tree/master/Parcelable-example/src/com/example/parcelable_example/model
Or is there an better to get the type of a parcelable object?
Related
I have an object that i must save to file for reuse. The class of this object already implements Parcelable for use in intents. My knowledge of saving an object to file says to implement Serializable, but when i do, i get an error in the class that contains this object at the putExtra method of an intent because both Serializable and Parcelable have this method.
Is there a way to avoid this, or just a way that i can save my object state and reload it easily?
I have looked at a few articles and i feel no more informed about how i should be saving my object.
Thanks in advance
I believe that Parcelable and Serializable both reaches the same goal in different ways and with different performances. Given that, if some class in your object hierarchy alread implements the Parcelable interface, you can override its writeToParcel method, call the super for it (so the members of the super classes will be written to the parcel if they were implement that way) and then, you should write your attributes to the parcel, always keeping in mind that the order you use to save them is the order you will use to retrieve them latter (FILO data structure)
EDIT
Just cast your object where it complains and tells about the conflict to the class you want to use as described here: https://stackoverflow.com/a/13880819/2068693
I don't know that you can implement both Serializable and Parcelable together but for convert a class from Serializable to Parcelable you can use this plugin:
Android Parcelable Code generator.
First remove implement Serializable then with ALT + Insert and click on Parcelable you can generate your class.
You have options other than Serializable, but that may meet other requirements such as avoiding library dependencies. You can write objects to file using JSON or XML, which has the advantage of being readable. You may also need to consider versioning - what happens when you have files that need to be read by a class that contains a new field. Persistence brings with it some issues you probably don't have passing Bundles/Intents back and forth.
If you choose Serializable I'd recommend structuring your objects so they can be written to and read from a Bundle. Using a static MyObject.make(Bundle) method and an instance Bundle save() method keeps all the constants and read/write in a single location.
I used to use Serializable objects to save them in filesytem and read them in order to do whatever I want. But Serialization is slow when you have to pass data between activities, so I read than it's recommanded to use Parcelable. Then I did it and yeah it's faster ! But now, I have a little problem. Since Parcelable is optimized for IPC, then they aren't serializable and can't be saved into a file. So I would to know if it's possible to do it.
Also, If I decide to implement both Parcelable and Serializable interface for my class, but only use the Parcelable to pass data between my activities, I would be able to save the class into a file. But I guess than since I use serializable (only to save, not to pass data), this is not a good idea hum ?
I thought too to use Gson library, to serialize data from class, and save the JSON into a file, and reuse Gson to deserialize JSON to get my Parcelable object. Does it seems to be a good idea ? What about performance ?
Thanks to all for your answers!
J.
Just do context.getFilesDir() and use a java.io.ObjectInputStream and java.io.ObjectOutputStream.
Also, with regard to "Parcelable not now serializable". This doesn't entirely make a lot of sense since Parcelable in an interface, not a class you extend.
So,
class MyClass implements Parcelable, Serializable {
}
should work just fine. Once you read and write the object to the file system, the Parcelable interface will still work. It's only an interface.
I have to admit I haven't tried it, but it's what I wrote today and I will be writing the unit test tomorrow.
Hope this helps.
Here's another approach if, as you say there is a conflict between the Parcelable and Serializable interfaces. (Again, that doesn't make sense, but I'll trust you until I finish my unit tests tomorrow)...
Think about this:
Parcel p = Parcel.obtain();
p.writeValue(asset);
p.setDataPosition(0);
byte [] b = p.marshall();
p.recycle();
OOPS, just read the javaDoc for marshall() and it says DO NOT STORE TO DISK. It also says, "Use standard serialization to store to disk" (paraphrase).
So, my first answer should do it for you.
Did you try to use shared preferences? If you need to store key values. Moreover it'll be an XML.
I'm trying to implement the parcelable interface using Gson. The idea is to create a json string (using gson) and write it to the parcel object.
Could it be a correct way to implement the interface?
The only problem I've encountered is when I deserialize the object. Actually, I use gson to recreate the object.
private MyClass(Parcel in) {
String json = in.readString();
Gson gson = new Gson();
gson.fromJson(json, getClass());
}
The problem is that the fromJson function returns an object that is the object the constructor should create.
The last line of code should be something like
this=gson.fromJson(json, getClass());
So, if this is a correct way to implement Parcelable, how could I solve this problem?
You should read more carefully the Parcelable javadoc. It contains everything you need.
As quoted in the docs :
Interface for classes whose instances can be written to and restored
from a Parcel. Classes implementing the Parcelable interface must also
have a static field called CREATOR, which is an object implementing
the Parcelable.Creator interface.
So you should have the writeToParcel method declared and also use a creator that will produce instances of your class from a Parcel.
The private constructor is an additional helper that you can use to set the value of the fields of an object given a parcel, but not the object itself. In Java, this is a right value, and can't be assigned.
BTW, the goal of parcelisation is to be provide a short term fast serialization process. You should, generally speaking, use a fast and compact data format when you use parcelisation. JSON is not a candidate of choice, but it will work.
The response I got to my previous question :
https://stackoverflow.com/questions/15489956/sending-data-structure-through-byte-android
states that I should look into serialization for converting my data to a byte array for transfer via bluetooth.
I have been looking into it but can't find any definite answer that states whether I am able to transfer a whole instance of an object, I was originally thinking of sending several arrays but now I am thinking maybe I can just create an object:
"Test"
parameters:
Test Name - String
Questions - Array of Strings
Question Answers - Array of Strings
Correct Answers - Array of Ints
My programming isn't that great so I was wondering, could I create this class, let the user on one device construct an object and then pass THAT object itself on through serialization (as shown in Java Serializable Object to Byte Array)
Will this ACTUALLY fully work and give me a whole object on the other system from which I can access the data elements I need?
Sorry if this is a stupid question but as I stated before my programming isn't that great and so I get confused sometimes :(
Thanks!
could I create
this class, let the user on one device construct an object and then
pass THAT object itself on through serialization
Short answer: Yes
But don't forget that class have to implement Serializable interface or NotSerializableException will be thrown.
Will this ACTUALLY fully work and give me a whole object on the other
system from which I can access the data elements I need?
Yes but this "other system" must know about this class. So if you create class
public class Foo implements Serializable {
private String name;
private int age;
// getters and setters
}
Application that want to deserialize object, must have this class in build path, simply said.
When bundling an object for later retrieval do I have to bundle objects within those objects?
For example, if I have an object that represents a player in a card game and within that I instantiate an object that represents the player's hand, do I have save the inner object to the bundle or is that automatically included with the outer one?
You cannot bundle any old Object, it has to be a String or a primitive such as boolean, integer, 'byte' or an array of these simple things. In this case yes, the contents of a String[] array are saved with the Bundle.
For more complex structures you can use implement the Parcelable in your object class, but it will be up to you to make sure the object saves all necessary information to it's Parcel and restores it.
java.ui.Serializable is something worth checking. It pretty much automates bundling class and its member variables as long as your class and all required members implement Serializable interface too.
http://www.tutorialspoint.com/java/java_serialization.htm