I'm not asking how do I use it nor what does it do, how does it works. The question came to me when I though why didn't they just put a putExtra(String,Object) so I can pass an object. Obviously they just didn't forgot to do it, rather than the way Bundle works isn't one you can just do that.
PS: Serializable or Parcelable is something you cannot implement on every class you create, so they are not a replacement for putExtra(String,Object)
Obviously they just didn't forgot to do it
Correct.
A Bundle itself is Parcelable, as Doctoror Drive notes. The point behind a Parcelable is to be able to place it into a Parcel, and the point behind a Parcel is to pass the data across process boundaries. You cannot pass arbitrary objects across process boundaries, just as you cannot write arbitrary objects to a file and cannot stream arbitrary objects over a socket.
Basically, a parcelable or serializable class are "transformed" in generic binaries with your package reference. This able you to transfer and persist data over databases, Intents and more.
The idea behind this is keep the state of some Activity or Fragment for example as a state machine.
By default, the system uses the Bundle instance state to save
information about each View object in your activity layout (such as
the text value entered into an EditText object). So, if your activity
instance is destroyed and recreated, the state of the layout is
restored to its previous state with no code required by you. However,
your activity might have more state information that you'd like to
restore, such as member variables that track the user's progress in
the activity.
Read more at Recreating an Activity.
Serializable
By default, the serialization mechanism encodes an object's class
name, the names of its non-transient fields (including non-public
fields), and the values of all of those fields. The output is an
opaque sequence of bytes. Those bytes can be decoded into a new,
equivalent instance as long as the decoder has compatible versions of
the originating classes. Changing the class name, field names or field
types breaks serialization compatibility and complicates
interoperability between old and new versions of the serializable
class. Adding or removing fields also complicates serialization
between versions of a class because it requires your code to cope with
missing fields.
Read more at: http://developer.android.com/reference/java/io/Serializable.html
Parcel
The bulk of the Parcel API revolves around reading and writing data of
various types.
Read more at: http://developer.android.com/reference/android/os/Parcel.html and http://developer.android.com/reference/android/os/Parcelable.html
Bundle documentation: http://developer.android.com/reference/android/os/Bundle.html
More links and posts
http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/
http://www.developerphil.com/parcelable-vs-serializable/
Benefit of using Parcelable instead of serializing object
Hope helped.
Bundle implements Parcelable so all the objects you pass must be valid for a Parcel, otherwise. Bundle can't be used passed as a Parcelable.
I'm not asking how do I use it nor what does it do, how does it works.
Bundle implements Parcelable, so it has to pass Objects to a Parcel. I would assume that Bundles are backed by HashMaps given their key, value nature.
Obviously they just didn't forgot to do it, rather than the way Bundle
works isn't one you can just do that.
You are right. They have not forgot it. Bundles can be used to do IPC (Inter Process Communication), so the system needs to know how to recreate an Object, hence Bundle implements Parcelable. This makes you confine to the same paradigm. If you have a custom Object it has to be able to tell Android how to re-construct itself across processes; hence it needs to implement Parcelable.
Related
I'm looking for a way of passing an object that I didn't create and cannot modify to implement parcelable in android. I was given a jar file that placed into the project by building a path to it. Now i need to pass the object created from activity to activity so that I may use the contents of the jar file. Right now it is set up so I define it as static, which probably isn't the best way. The only other option I can think of is using putSerializable but I've heard that puts strain on the system. So, what are my other options?
The main problem you have here is if that class has non-accessable private fields (through getters), then you cannot get this data to parcel it. If all private fields are accessable, then you might have several possibilities:
Extending it with a Parcelable subclass (as suggested by Simon in the comments).
Wrapping it in another Parcelable object.
Converting it to an already Parcelable object (e.g. any implementation of Map)
Note that if the object itself is not very big then the performance drop between parcelling and serializing shouldn't be noticeable. So I would go for Serializing and if the performance is not satisfactory then consider other options.
I've been just wondering if there is a way to modify variables from a different activity from which they were created. Precisely, I would like to modify a list in Activity1 from Activity 2, is there a way to give a reference to that list from the other activity? putExtra() method does not accept List as input parameter and I don't think startActivityForResponse() is what I'm looking for either. I don't know if some kind of shared variables exist or something alike.
Is it possible to do that?
Thanks in advance.
May be this is not the very good solution but what you can do is that you can create DataManager as single Instanse that Hold Linklist of data. In each activity you can get instance of data-manager and update data in it.
You can pass the entire list as an extra, you just need to serialize it by making it a parcelable first.
A Container for a message (data and object references) that can be sent through an IBinder. A Parcel can contain both flattened data that will be unflattened on the other side of the IPC
A bit confusing to understand, but all it really does is flatten the data into strings/ints/other primitive types so that it can be passed easily. On the other side, it's re-build into your list structure.
This is the tutorial I used when I did something similar:
http://prasanta-paul.blogspot.ca/2010/06/android-parcelable-example.html
I need to pass a List of my objects between activities. I do not want to use parcelable or serialize the data each time. I also do not want to save it in a local file or database. That probably leaves me with using static objects.
Lets say I to use ListA between activities Activity1 to Activity2. I ca
Approach1: Create a static ListA in one of those activities and do all my stuff of that static ListA.
Approach2: Create a static list in another class which I use just for storing this List and doing all my stuff on this list. But this means that this stays as long as my process is running and I have to manually set it to null when I do not need it.
Approach3. I am extending the above class to implement it using a static HashMap.
I have two methods one to store the list in a static HashMap using a unique key and another method to retrieve the list and remove it each time data is retrieved so that the List is no longer present in the static HashMap. So we essentially have to pass only the random key generated to store data between activities which I can pass as an extra using Intents.
Will there be any issues when I use any of the above approaches and which will be the best approach.
I'd consider creating an Application object and using it like a singleton to access your data. I've described the approach here: http://chrisrisner.com/31-Days-of-Android--Day-7%E2%80%93Sharing-Data-Between-Activities. Some people don't seem to like using the Application object in this manner but it makes more sense to me than putting a static object on an Activity.
Uggg statics! Man I wish all developers understood global variables are bad and how they make your program more brittle and your life hell. We only been talking about how bad they are for 30+ years, but unfortunately no one figures this out until they've utterly hung themselves on them.
First I'll say serializing your data is fast. There are great tools out there that will serialize your objects quickly that you can use I prefer http://flexjson.sourceforge.net for this.
So if you are just outright opposed to this you can pass this object through the Application by subclassing it, declaring your implementation in your Android Manifest, and each activity has access to the Application instance:
public class MyActivity extends Activity {
public void onCreate( Bundle bundle ) {
MyApplication application = (MyApplication)getApplication();
Object anInstanceFromAnotherActivity = application.getSomeInput();
}
}
The downside to this is when your application is reclaimed if the user returns to your application the memory is gone, and you can't get that input you might need of your screen. Android framework is trying to make you serializing things in the bundles because if it decides to destroy your application you can always rebuild yourself from the bundle. Now there are short cuts you can take like redirecting people to start over if the Application has been reclaimed, but those depend upon your program and what its doing if they make sense.
That's where using serialization wins out over all other forms of persistence (parcelables, files, databases) because it can be done in one line of code.
I want to pass a client object to a diffrent activity on android
I know how to pass strings but have no idea about passing objects.
myIntent.putExtra("nick",nick);
where nick is a string
how do i pass an object say Client c?
"If you're just passing objects around then Parcelable was designed for this. It requires a little more effort to use than using Java's native serialization, but it's way faster (and I mean way, WAY faster)."
How to send an object from one Android Activity to another using Intents?
If the activity you are passing the object to is your own, serialize the object into a string and deserialize in the activity. http://java.sun.com/developer/technicalArticles/Programming/serialization/
Or as answered here: How to pass an object from one activity to another on Android
Think hard about whether you need to send the object or if you really just need a few data elements out of the object. Sending the primitives or Strings will likely be much simpler (= faster, potentially less buggy) if it's enough to meet your needs.
If you do need to pass an object then you could either implement the Parcelable interface or you could put the object into a static variable (of type List, Set, Map, etc.) in another class and reference it that way. There are drawbacks to these approaches and I would only recommend them if you can't get by passing the actual data values you need through the bundle.
Caveat: the standard line is use simple primitives/Strings as name:value pairs, prefer parcelable over serializable
The argument is that passing serialized objects is inefficient, so do not do it. For a small object I am not so sure that this is a real world concern. It has been argued for readability and clarity over efficiency unless you detect poor performance. So far with a small object I have not detected any performance problems. IMHO, using the fully qualified name of the class in the name:value pair and serializable objects makes the code readable, simple , less buggy, easier to maintain and is easy to implement during prototyping. If performance problems are detected, or you have time to refactor the code base, then the serializable code can be converted to Parcelable code once the object properties have stabilized.
OK. I am putting on my flame suit.
Suppose you want to start a new activity and pass it some data from the current activity. If the data is of a primitive type you could simply use an intent and add extras, but how would you do this for more complex data structures like arraylists or objects?
You have a few options:
You could wrap the more complex structure in a class that implements the Parcelable interface, which can be stored in an extra
You could wrap the more complex structure in a class that implements the Serializable interface, which can be stored in an extra
You use static data members to pass stuff around, since they are all in the same process
You use external storage (file, database, SharedPreferences)
As the person who just posted noted, use a common component, such as a custom Application or a local Service
What you do not want to do is pass big stuff via extras. For example, if you are creating an application that grabs pictures off the camera, you do not want to pass those in extras -- use a static data member (icky as that sounds). Intents are designed to work cross-process, which means there is some amount of data copying that goes on, which you want to avoid when it is not necessary for big stuff.
One option I am aware of is storing the data you are using in an Application object which all your activities can retrieve from context.
I have also heard of using Google Protocol Buffer to achieve a higher performing solution