Why does Android use parcels to pass data between components (e.g. two Activities)? Why not just a reference to the object?
Parcel is a container for a message(data and object references). In transmission, Parcel contains a byte stream version of a chosen Java Object that contains information about it's attributes. Such data is written to Parcel at sending component, and is read at receiving component. Because the protocol is also designed to support IPC(Inter-Process Communication), only a reference wouldn't suffice. If you really want to use just a reference you can declare your object containing data public static, although I wouldn't recommend this because of the global scope & tight coupling of components.
If we look at common ways of sharing data between activities, we can make a reasonable guess at why this is the case.
Alternatives include using singletons and SharedPreferences - entities that basically act as "owners" of the state stored by the data. The use of a third party keeps the activities decoupled, as compared to activities simply giving each other references.
We want activities to be decoupled since any two activities should be fairly distinct entities, with possibly independent lifecycles. This is why if we can simply pass information by value (rather than keep a live reference dependency), we should. This is also why it's comparable to Inter-Process Communication, which works around the lack of shared memory.
Related
I know that I can add a string or an integer by putting putextra() on my Intent but what do I do if I have to send a List?
For example, My main activity contains a list, I have a different activity that adds an item into the list and I have a third activity that needs to show the whole list
Your object can also implement Parcelable interface. Then you can use Bundle.putParcelable() method and pass your object between activities within intent.
Photostream application uses this approach and may be used as a reference http://code.google.com/p/apps-for-android/
Source: google "pass objects between activities android" :)
By making the Activity the central focus of the Android API, both in the API documentation and in most of their examples, Google has encouraged inexperienced developers to treat Activities as the sole constructs in an Android application. And, unfortunately, most of the widely available literature and over-simplified code examples available on the web perpetuate this.
However, good software design, regardless of platform or programming language, would suggest that you use the concept of a data 'model' - a class that contains the data that is important to your application, as well as methods that operate on that data. This class should be independent of any user-interface-related classes.
Activities are essentially a mash-up of Views and Controllers from the point of view of the popular Model-View-Controller (a.k.a. MVC) design pattern.
You should strive to remove the management of your data from the Activities, and put it elsewhere, in a non-Android class. Then make that class available to the Activities that need it, instead of simply passing data from Activity to Activity.
Where to put this model class? There are a number of ways to do it, including, but not limited to:
Make it a member of your Application class (subclass Application if you haven't already) - this is simple and convenient, but only reasonable for very small applications - it quickly gets out of hand
Make it stand-alone, but make all of the data members and methods static - again, simple and convenient, but only for a very small amount of data
Use a dependency injection library (e.g. Dagger), make it a Singleton, and inject into the Activities that need it.
I'm a C/C++ guy, and I'm quite new to Java and Android.
So I'm creating a class instance in Activity "A" and I'm trying to use this instance to Activity "B". In C/C++ you would simply pass the address (pointer) of the instance.
Now I learned that with Android I should use a Parcel, but I don't get the idea: why would I want do all that parceling/deparceling procedure when all I want to do is passing a pointer?
Please enlighten me!
This is related to the Android activity model.
Since your app may be killed by the system to recover RAM (this should only happen when it's in the background, unless the system is in a really bad situation), an object reference just won't do. It'd be completely worthless once your process dies.
The intent you use to start activities is saved by the Activity Manager, so that it can be used to recreate your activity when the user navigates back to it. That's why all the data in your intent has to be parceled.
Keep in mind that this means that your two activities will have two similar instances -- but naturally, they will not be the same object, so changes to one won't be reflected in the other.
Parcel or parcalable is an efficient and alternative way to serialize objects in Android. Its an alternative to Serialization in core Java.
Java Serialization API allows us to convert an Object to stream that we can send over the network or save it as file or store in DB for later usage.
Its a way to exchange objects between sender and receiver(Class). Receiver than deserializes this object.
In Android parcel is used to exchange objects between different activities by using Intents.
java doesn't work like c/c++, you don't work directly with the memory. If you want to pass an object from A to B, you have to set it in a Bundle, and add that bundle to the intent. if it's a custom class, let's call it C, C should implement parcellable. Java works by value, not by reference.
custom parcelable objects
how do i pass data between activities?
I have been wondering for a while now in this question on stack overflow one solution for passing complex data in-between activities on Android is the usage of static data members.
But somehow I get the feeling that this is not the way how you should do it even thou it seems to be the easiest way.
Therefore my question what is the downside of using static members for passing complex data.
A static reference to pass data between components could be used if all of these conditions are met:
It is only accessed via 1 process
The data it contains does not hold a reference to any specific component (Activity, Fragment, Service e.t.c) except for the Application (which is a static singleton anyway)
The data does not keep a reference to anything else that may not have the same life cycle as the data
The data is too complex, or large to reasonably Serialise, Parcel or otherwise pass via Bundles, and doing so would effect the performance of the application.
It is correctly synchronised if accessed from different threads
The data is correctly managed and released when no longer required, avoiding leaking the memory needed to store it
Since these are quite restrictive conditions, a different approach (some suggested by gmale) is usually better.
The biggest drawback in my opinion is the management of the static data - it is usually difficult to tell when the data is no longer needed and when it can be released.
Using static members should be avoided. It's one of the worst ways to pass data in Android. Static objects persist beyond the application's lifecycle. So a user can back out of your app and your data lives on because the class is still loaded in the JVM. That's very bad.
Sometimes, Otto can be a good option for passing complex data around and it plays nicely with the Activity Lifecycle. Another alternative I've seen on many projects is good old fashioned listeners or callbacks. There's also intent services and local broadcast managers.
There are a lot of ways to share complex data. I would consider "static" objects a non-starter. Avoid them like the plague.
I want to know exact ,
whether should I used parcelable or serialization technique
for sending data from one activity to other?
is it compulsory to
use one of them for sending data from one to other?
when should I use them?
and the exact difference between them and performance
of both of them in java aspects.
Thanks in advance.
public class GetSetClass implements Serializable {
private int dt = 10;
/** pass any object, drwabale */
public int getDt() {
return dt;
}
public void setDt(int dt) {
this.dt = dt;
}
}
These concepts are related to Inter Process Communication (IPC).
When sending data between two applications, we have to make sure that both applications should understand the format of the data that is being sent.
Especially when you are sending non primitive data type values like classes and objects between two applications, We have to convert them into Operating System understandable format. O.S understands only primitive types (ints, chars etc). The reason for conversion is we have to O.S communication channel to transmit the data.
This process of converting Non primitive types to primitives and sending across to other application over some communication channel is called as Serialization. The reverse process is called as De Serialization.
In Java, IPC depends heavily on Serializables for serialization. But serialization is designed by keep desktop applications in mind. When you are doing IPC in mobile applications we have to make sure that the process of IPC is not too heavy.
In simple terms serialization is a heavy concept for IPC.
So in place of Serialization Android opted for Binders for achieving light weight Inter process communication. Binders internally depends heavily on parcels, to do the IPC.
Parcels are light weight serializables. It is preferred to use parcels for marshaling objects into byte streams.
Note: Binder IPC heavily depends on Shared memory concept to make sure that there is not much data duplication while sharing between applications.
whether should i used parcelable or serialization technique for sending data from one activity to other.
If you are sending a non-primitive type data/Object to another activity through the intent you have to either Serialize or implement Parcelable for that object. The preferred technique is Parcelable since it doesn't impact the performance.
is it compulsory to use one of them for sending data from one to other. / when should i use them.
It is only compulsory/used for sending non-primitive type data objects.
and the exact difference between them and performance of both of them in java aspects.
Serialization does impact the performance. For more details check this link Android Parcelable and Serializable
Got a very good explanation of difference between Parcelable and Serialization.
To start with your question though its been a long time, it may help others:
whether should I used parcelable or serialization technique for sending data from one activity to other?
Ans: Parcelable is best choice (why explained later).
is it compulsory to use one of them for sending data from one to other?
Ans: Yes, as sending data (object) from one to other requires streams of bytes to be written and retrieved and that can be done either through parcelable or serialization.
when should I use them?
Ans: This part you arleady answered i.e, passing data from one activity to another.
and the exact difference between them and performance of both of them in java aspects.
Ans: 1. Parcelable is well documented in the Android SDK; serialization on the other hand is available in Java.
In Parcelable, developers write custom code for marshaling and unmarshaling so it creates less garbage objects in comparison to Serialization. The performance of Parcelable over Serialization dramatically improves (around two times faster), because of this custom implementation.
Serialization is a marker interface, which implies the user cannot marshal the data according to their requirements. In Serialization, a marshaling operation is performed on a Java Virtual Machine (JVM) using the Java reflection API. This helps identify the Java objects member and behavior, but also ends up creating a lot of garbage objects. Due to this, the Serialization process is slow in comparison to Parcelable.
Answer taken from:
this link
See also:serialization explained
Java Serializable:-
Serializable comes from standard Java and is much easier to implement all you need to do is implement the Serializable interface and add override two methods.
The problem with Serializable is that it tries to appropriately handle everything under the sun and uses a lot reflection to make determine the types that are being serialized. So it becomes a beefy Object.
Androids Parcelable:-
Android Inter-Process Communication (AIPC) file to tell Android how is should marshal and unmarshal your object.It is less generic and doesn't use reflection so it should have much less overhead and be a lot faster.
Read More from http://www.3pillarglobal.com/blog/parcelable-vs-java-serialization-android-app-development
both parceling and serializing are ways to marshall and unmarshal data. in android this is used to pass non-primitive data types between components and processes. in general, android allows either serializable or parcelable objects, so you can choose your method. the exception to that is with AIDL interfaces. objects must be parcelable to be passed / returned.
serialization uses reflection to automatically marshall and unmarshal data. in most cases implementing the marker interface is enough to make it just work. with parceling, you have to write the code to marshall and unmarshal the data yourself.
and hence, that is why parceling is faster. the object does not need to be reflected to discover the fields. it's the reflection that makes it slow.
serialization also has in-built versioning ... if you try to unmarshal to a different version of the object's class that was marshalled, the process will fail in a predictable way. with parceling, you can do the same thing but you need to implement it yourself by adding a "version field to your object, and code that checks the version when unmarhsaling.
that being said, i typically use serialization. with simple objects you won't notice the difference. you can always change to use parceling later in development if you discover performance issues.
I know this question has been asked multiple number of times and i have been through a lot of these questions......almost all of these questions throw up the use of the parcelable interface for your class.
However in a couple of questions i came across a quotation:
"NOTE: Seeing Parcelable might have triggered the question, why is Android not using the
built-in Java serialization mechanism? It turns out that the Android team came to the conclusion
that the serialization in Java is far too slow to satisfy Android’s interprocess-communication
requirements. So the team built the Parcelable solution. The Parcelable approach requires
that you explicitly serialize the members of your class, but in the end, you get a much faster
serialization of your objects.
Also realize that Android provides two mechanisms that allow you to pass data to another
process. The first is to pass a bundle to an activity using an intent, and the second is to pass a
Parcelable to a service. These two mechanisms are not interchangeable and should not be
confused. That is, the Parcelable is not meant to be passed to an activity. If you want to start
an activity and pass it some data, use a bundle. Parcelable is meant to be used only as part of
an AIDL definition."
This quote can also be found in the book Pro Android 2.
Now seeing that all activities within the same application run in the same process(Every Activity in Android is a Process,or One Application is one process),unless otherwise specified in the manifest,communication within the activities of the same application is not Interprocess communication per se.So is it really faster to use the parcelable class or is it just enough to pass your object attributes through bundle via intent ?
Shedding any light on this aspect will be largely appreciated.
Cheers !!
There's a FAQ for that. :)
The short answer is that the Android team recommends three techniques for passing data between activities and services within an app: a singleton class; a public static field or method; a HashMap of WeakReferences to Objects (and you pass the key in the intent). The major issue to keep in mind is how your data is going to behave under various lifecycle events. (For instance, if the user turns the phone, by default your activities will be destroyed and recreated; your data handling method needs to be designed with that in mind.)
The Parcelable construct is designed to be very fast at passing data across application memory boundaries: within an application you are MUCH better served using Bundle because all the memory locations the data is stored in are accessible to both the sender and the receiver. Since the in-memory objects are accessible there is no need to incur the cost of reconstruction: just use the Bundle, which is really just a glorified HashMap with type-specific put/get methods.
For AIDL and IPC purposes you can't (by default) share memory locations so you need an efficient way of moving data: this is where Parcelable kicks in. Unless one of the components of your application is using the remote process capability then there is no need to use Parcelable.
From docs:
Parcelables
The Parcelable protocol provides an extremely efficient (but
low-level) protocol for objects to write and read themselves from
Parcels. You can use the direct methods writeParcelable(Parcelable,
int) and readParcelable(ClassLoader) or writeParcelableArray(T[], int)
and readParcelableArray(ClassLoader) to write or read. These methods
write both the class type and its data to the Parcel, allowing that
class to be reconstructed from the appropriate class loader when later
reading.
There are also some methods that provide a more efficient way to work
with Parcelables: writeTypedArray(T[], int), writeTypedList(List),
readTypedArray(T[], Parcelable.Creator) and readTypedList(List,
Parcelable.Creator). These methods do not write the class information
of the original object: instead, the caller of the read function must
know what type to expect and pass in the appropriate
Parcelable.Creator instead to properly construct the new object and
read its data. (To more efficient write and read a single Parceable
object, you can directly call Parcelable.writeToParcel and
Parcelable.Creator.createFromParcel yourself.)
Bundles
A special type-safe container, called Bundle, is available for
key/value maps of heterogeneous values. This has many optimizations
for improved performance when reading and writing data, and its
type-safe API avoids difficult to debug type errors when finally
marshalling the data contents into a Parcel. The methods to use are
writeBundle(Bundle), readBundle(), and readBundle(ClassLoader).