Aidl special handling for passing complex type objects
It has been described earlier that passing the system's allowed data through the Aidl interface, if a complex type of object needs to be passed, is less straightforward and requires some extra processing. As follows:
In the Aidl file that defines the data interface, use the Parcelable keyword, for example: Parcelable message;
Implement the Parcelable interface in its data implementation class and implement the corresponding method.
In the Aidl file of the business interface, use import to introduce the package name of the data interface Aidl.
For example: Message.aidl
1 parcelable message;
For example: Igetmsg.aidl
1 package com.example.aidlservicedemo.domain;
2
3//This is two custom classes
4 Import Com.example.aidlservicedemo.domain.Message;
5 Import Com.example.aidlservicedemo.domain.User;
6
7 Interface igetmsg{
8//Define a Getmes method in the Aidl interface
9 List getmes (in User us);
10}
Parcelable and Parcel Interface
To start with the Android object serialization, there are two main ways to serialize objects in Android, either to implement serializable interfaces or to implement parcelable interfaces. The serializable interface is javase native supported, and the Parcelable interface is unique to Android, and its serialization and deserialization efficiency is higher than the serializable interface, and Aidl is in interprocess communication (IPC), Is the need to implement this parcelable interface.
Parcelable interface function: the implementation of the Parcelable interface instance, can write its own data information to a parcel object, can also be restored from parcel to the object's state. And parcel is the carrier that completes data serialization writing.
The above mentioned parcel, and then to talk about parcel is what? Android system design at the beginning, positioning is for memory-constrained devices, so the performance requirements are better, so the system using interprocess communication (IPC) mechanism, must require better performance of the serialization method, so parcel was designed, Its positioning is a lightweight and efficient object serialization mechanism and deserialization mechanism. If you read the underlying code for Android, you'll find that parcel is implemented using C + +, and the bottom layer directly operates on the parcel pointer, so it's more efficient.
Parcel also provides a series of methods to help write data and read data, here is a brief introduction:
Obtain (): Gets a new parcel in the pool.
DataSize (): Gets the actual storage space of the current parcel object.
Datapostion (): Gets the offset of the current parcel object.
Setdataposition (): Sets the offset of the current parcel object.
Recyle (): Empties and reclaims the memory of the current parcel object.
Writexxx (): Writes data to the current parcel object with multiple overloads.
READXXX (): reads data from the current parcel object with multiple overloads.
In simple terms, Parcelable uses the Writetoparcel () method to serialize the data written to a complex object parcel, and then, when needed, through the static properties defined inside Creator.createfromparcel () An operation that is deserialized. The parcelable is packaged with parcel, whose interior is serialized and deserialized by manipulating the parcel.
Parcelable and parcel are both defined under the Android.os package, and this mechanism is not only used for aidl, but also for intent to pass data and other places, this is not the theme of this blog, later used in detail.
Implement Parcelable interface
After defining the Aidl file of the data interface, we need to define a data implementation class, implement the Parcelable interface, and implement the corresponding method, parcelable have the following abstract methods that must be implemented:
abstract int describecontents (): Returns a bitmask representing the parcelable of a particular set of object types, typically returning 0.
asbtract void Writetoparcel (Parcel dest,int Flags): Implements serialization of objects, serializing objects through a series of Parcel () methods of writexxx.
In addition to the above two methods, you also need to define a generic static property named "CREATOR" with Type "parcelable.creator" in the implementation class, which implements the deserialization of the object. It also has two abstract methods that must be implemented:
Abstract T Createfromparcel (Parcel source): Deserializes a Parcelable object by using the source object to serialize data based on the Writetoparcel () method.
Abstract t[] NewArray (int size): Creates an array of new Parcelable objects.
For example:
1 @Override
2 public int describecontents () {
3 return 0;
4}
5
6 @Override
7 public void Writetoparcel (Parcel dest, int flags) {
8 log.i ("Main", "Server message is serialized");
9 Dest.writeint (ID);
Dest.writestring (Msgtext);
One dest.writestring (fromname);
Dest.writestring (date);
13}
14
public static final Parcelable.creator Creator = new Creator () {
16
@Override
Message[] NewArray (int size) {
Return to new Message[size];
20}
21st
@Override
Public message Createfromparcel (Parcel source) {
LOG.I ("main", "service-side message is deserialized");
Return to New Message (Source.readint (), source.readstring (),
Source.readstring (), source.readstring ());
27}
28};
As you can see from the example above, using the Writetoparcel () method for serialization, Deserialization through Creator.createfromparcel, they all pass an object of parcel type, where it is important to note that the writexxx () and Readxxx () methods of the parcel objects in the two methods must be in the same order. Because the general serialization data is serialized as a chain, the deserialized data can be faulted if the order is not correct.
Aidl Pass Complex Type Object demo
As the key points are already mentioned, the following is a simple demo to demonstrate Aidl passing complex objects.
Aidl Interface:
Com.example.aidlservicedemo.domain.Message.aidl
Message.aidl
Com.example.aidlservicedemo.domain.Message.java
Message.java
Com.example.aidlservicedemo.domain.User.aidl
User.aidl
Com.example.aidlservicedemo.domain.User.java
User.java
Service:
Com.example.aidlservicedemo.
Customtypeservice.java
Client:
Com.example.aidlClientdemo.
Customtypeactivity.java
Effect Display:
Aidl the process of passing object serialization
Through the above demo printed log, explain the serialization process, open logcat view log.
You can see from the PID column above that this is the interaction between two threads.
The process is like this, the client passes a user object to the server, the server processes the data through the user object, and returns two message objects to the client.
First, before the client is passed to the server-side user object, the client serializes the user object before passing it to the server, and the server receives a serialized piece of data, which deserializes the data according to the original rules, and then processes the user. When the server found that the user has two message, the two message objects need to be passed to the client, the message object is serialized before delivery, the client receives the serialized data passed by the server, and then deserializes the correct object according to the established rules.
From this process, you can see that the data passed between processes must be serialized, otherwise it cannot be delivered. For those data types (int, double, String, list, etc.) that are aidl by default, they are actually serialized internally, so there is no need for us to specify the serialization rules. But for complex type objects, the system cannot know how to serialize and deserialize, so we need to specify the rules.