Passing objects in android - android

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.

Related

When to make an Object parcelable rather than just sending the primitive variables?

After researching for a while there is still something unclear for me:
When is it worth to implement Parcelable rather than just getting the variables and send them to a new Activity?
If i search for example for something like "RecyclerView click open new Activity", almost everyone posts code that extracts the values with getter methods in Activity 1 and sends them via multiple .putExtra calls to Activity 2. Almost no one seems to suggest to implement Parcelable.
I also fail to see where Parcelable saves effort or makes the code more maintainable, since i have to call .getXXX for every value in the target Activity anyways.
So let's say I have a RecyclerView, I want to open a new Activity on Button click and i want to send 3 variables out of 1 Object from 1 ArrayList. Should i send the variables directly over 3 .putExtra calls or implement Parcelable and send the whole Object?
In your case sending the 3 primitive values with putExtra should be enough. Parcelable is to send objects. Normally these objects contain objects which contain other objects or array of objects. In summary it is used to send complex objects. It's also necessary if you need to send an object to your service as part of the body of a request.
Don't use Parcelable if u have less no. Of data elements because serialization itself take some time. But sending them individually will be faster.
Using parcelable for something as trivial as this would be an overkill as it involves the overhead of constructing a new object for only a few values. It would be better if you just add the .putExtra() calls for the values you need to share, that should be enough, as the others before me said. :)

How does Bundle works?

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.

Passing objects in Android that I didn't create?

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.

Best way to make nested custom objects parcelable in Android

There is a lot of information out there concerning Parcelable in Android. After looking around, I couldn't find a nice solution for my problem.
So, I need to create a class (let's call it "MyClass") which extends a custom class someone else wrote ("HisClass"). There are many instance variables in HisClass, some of which are objects of custom classes, themselves. I want to pass a MyClass object from one activity to another and I realize, I need to make it Parcelable. But what about the instance variables which are custom objects?
Reading this, I think I need to make every single custom object implement Parcelable. Since, there are many custom objects in MyClass and HisClass which again have custom objects for instance variables, doing that seems like a bad solution to me.
Is there a better way? Maybe, I am just being totally blind here. Hope someone can help me.
Well, you can make use of Serializer, but it would result in a slow performance. AFAIK, implementing Parcelable is the best way to passing data. Additionally, don't try to complicate yourself by creating so much complex data structure to pass using Intent.
Either use Parcelable for something cheap/light-weight/less-in-amount or something else like output to files...and passing its paths.

Why use parcelable when you can perform the same task using static variables?

i am new in android and java ... i am reading from couples of day about android parceling tutorial for transfer data or variables values from one activity to other or one class to other ... but i am not so understood about that.
can u tell me that is it necessary to use Parcelable for this purpose because same task can also be perform using static key word for variables as string,int or array type then why parcelable pls explain in detail ..
thanks for explanation in advance please provide comparison with example
While technically both approaches will work, there are a couple of flaws.
The first is that the static variable is static. If you have two instances of the same activity, they will both reference the same static object. This is probably not what you want.
Secondly, it's considered bad practice to access global variables. It makes it difficult to see what is going on, is difficult to test and you someone (another class) can modify your data. This creates some horrendous bugs.
By passing the data via a Parcelable object it is very clear what you are doing and you avoid both of these problems.
Note that this advice is not specific to Android, rather to Java and programming in general.
Static references never get garbage collected so you end up creating something called a memory leak.
You are keeping an object in memory that you don't need and it can't be freed up.
If you instantiate enough objects like this you will get an out of memory (oom) exception which will cause the app to crash.

Categories

Resources