Introduction of Android serialization
We already know that the object needs to be serialized when Android uses Intent/bindler to transmit data to the IPC.
Java has already provided the serializable interface for serialization and is very simple to use, primarily for object persistence and for network transmission of objects. The serializable overhead is large because the serialization and deserialization process requires a lot of I/O operations.
Android provides the Parcelable object serialization operation is memory serialization, mainly used for Intent/bindler IPC data transfer.
Second, the use of Parcelable serialization method
For example, we use parcelable to transfer a book object directly through the intent in two activity.
1 PackageOrg.xerrard.demo2;2 3 ImportAndroid.os.Parcel;4 Importandroid.os.Parcelable;5 6 /**7 * Created by Xuqiang on 16-1-20.8 */9 Public classBookImplementsparcelable{Ten One PublicString bookname; A - PublicBook (String bookname) { - This. BookName =BookName; the } - - protectedBook (Parcel in) { -BookName =in.readstring (); + } - + Public Static FinalCreator<book> Creator =NewCreator<book>() { A @Override at PublicBook Createfromparcel (Parcel in) { - return NewBook (in); - } - - @Override - PublicBook[] NewArray (intsize) { in return NewBook[size]; - } to }; + - @Override the Public intdescribecontents () { * return0; $ }Panax Notoginseng - @Override the Public voidWritetoparcel (Parcel dest,intflags) { + Dest.writeint (bookname); A } the}
We need to complete the following several.
1. Implement the Parcelable interface
2. Adding Entity Properties
3. Overwrite the Writetoparcel (Parcel dest, int flags) method, specifying the data written to the Parcel class.
4. Create Parcelable.creator static object, there are two methods Createfromparcel (Parcel in) and newarray (int size), which specifies how to read out the data object from Parcel, which creates an array.
5. Overwrite the Describecontents method, return 0 by default.
We can then use the Putextra method in intent to write the book object to intent, and then use the Getextra method to read the book object from the intent.
Third, the principle of parcelable underlying serialization
As you can see from the above example, the serialization of parcelable is cumbersome to use. However, this is a good way to be efficient, because the parcelable serialization process is the native of the underlying memory operation.
Detailed JNI and the underlying memory operations of C/C + + can see this article explore the parcel mechanism in Android (above)
The most important conclusion in the excerpt
The entire read and write is done in memory, primarily through memory operations such as malloc (), realloc (),memcpy (), so efficiency is much higher than using external memory in Java serialization
Therefore, in the IPC process, Android recommends the use of the Parcelable serialization method
Four: Parcelable of the call relationship
We know that if you want to use parcelable, you must implement these five operations as required
1. Implement the Parcelable interface
2. Adding Entity Properties
3. Overwrite the Writetoparcel (Parcel dest, int flags) method, specifying the data written to the Parcel class.
4. Create Parcelable.creator static object, there are two methods Createfromparcel (Parcel in) and newarray (int size), which specifies how to read out the data object from Parcel, which creates an array.
5. Overwrite the Describecontents method, return 0 by default.
What is the invocation relationship in this?
We see that Writetoparcel is a step-by-step call in the process of startactivity, and then Writetoparcel calls the native method, Make a serialization operation at the bottom
Createfromparcel is a step-by-step call by Intent->bundle->parcel after receiving intent.
It can be seen that the parcel package is inseparable from the bundle.
There is actually a question here, what is the creator?
Let's take a look at this part of the creator from the source.
1 Public Final<textendsParcelable>T readparcelable(ClassLoader loader) {2Parcelable.creator<t> Creator =readparcelablecreator (loader);3 if(Creator = =NULL) {4 return NULL;5 }6 if(creatorinstanceofParcelable.classloadercreator<?>) {7 return((parcelable.classloadercreator<t>) creator). Createfromparcel ( This, loader);8 }9 returnCreator.createfromparcel ( This);Ten } One A /**@hide*/ - Public Final<textendsParcelable> TReadcreator(parcelable.creator<t>Creator, - ClassLoader Loader) { the if(creatorinstanceofParcelable.classloadercreator<?>) { - return((parcelable.classloadercreator<t>) creator). Createfromparcel ( This, loader); - } - returnCreator.createfromparcel ( This); + } - + /**@hide*/ A Public Final<textendsParcelable> parcelable.creator<t> readparcelablecreator( at ClassLoader Loader) { - String name = readString ();//Get the class name here, it's not clear how to get it, if you want to study further - if(Name = =NULL) { - return NULL; - } -Parcelable.creator<t>Creator; in synchronized(mcreators) { - hashmap<string,parcelable.creator> map = mcreators.get (loader); to if (map = = null) { map = new hashmap<string,parcelable.creator> (); mcreators.put (loader, map); Creator = map.get (name); $ if(Creator = =NULL) {Panax Notoginseng Try { - Class c = Loader = = null ? Class.forName (name): Class.forName (name, true, loader); the Field f = C.getfield ("CREATOR"); Creator = (parcelable.creator) f.get (null); the } + Catch(illegalaccessexception e) { -LOG.E (TAG, "illegal access when unmarshalling:" $+name, e); $ Throw NewBadparcelableexception ( -"Illegalaccessexception when unmarshalling:" +name); - } the Catch(ClassNotFoundException e) { -LOG.E (TAG, "Class not found when unmarshalling:"Wuyi+name, e); the Throw NewBadparcelableexception ( -"ClassNotFoundException when unmarshalling:" +name); Wu } - Catch(classcastexception e) { About Throw NewBadparcelableexception ("parcelable protocol requires a" $+ "Parcelable.creator object called" -+ "CREATOR on class" +name); - } - Catch(nosuchfieldexception e) { A Throw NewBadparcelableexception ("parcelable protocol requires a" ++ "Parcelable.creator object called" the+ "CREATOR on class" +name); - } $ Catch(NullPointerException e) { the Throw NewBadparcelableexception ("Parcelable protocol requires" the+ "The CREATOR object to being static on class" +name); the } the if(Creator = =NULL) { - Throw NewBadparcelableexception ("parcelable protocol requires a" in+ "Parcelable.creator object called" the+ "CREATOR on class" +name); the } About the Map.put (name, creator); the } the } + - returnCreator; the}
Focus on the bold part of the code--really want to white:
After receiving the parcel, the creator of the object is retrieved by reflection, and then saved to a hashmap. Then call creator's Createfromparcel method to implement the unpacking.
Reflection in the source code is also everywhere!
An analysis of the parcelable of Android object serialization