Communication between Android processes using AIDL and androidaidl
AIDL (Android Interface Definition Language) enables inter-process communication and allows multi-thread access. (If inter-process communication is required and multi-thread access is not required, it is more appropriate to use the Messenger method.) To implement AIDL, the following steps are required.
1. Define the AIDL Interface
The suffix of the AIDL interface is. aidl file (for example, create an IRemoteData. aidl), which is written in java syntax. during compilation, the Android sdk will generate a java file (IRemoteData. java), this file contains a static internal abstract class Stub, inherits the Binder class and implements the interface (IRemoteData ). It provides an asInterface (android. OS. IBinder obj) to convert the IBinder object to the interface type we declare (actually, it is the implementation of Stub on the Service side ).
AIDL supports the following data types: java basic data types (int, char, boolean, etc.), String, CharSequence, List, and Map. If you want to use other data types in AIDL, you must use import, even if the type and aidl are in the same package. Second, all non-original data types must specify the parameter direction. input parameters are represented by the keyword in, outgoing parameters are used out, incoming outgoing parameters are used inout, and basic data types are used as input values.
1 package com.young.testserver.aidl; 2 3 import com.young.testserver.aidl.Person; 4 5 interface IRemoteData { 6 int getRemoteData(); 7 void setRemoteData(int data); 8 9 Person getPerson();10 void setPerson(in Person person);11 }
Since this aidl file uses a non-original data type Person, you need to create an aidl file to declare the Person
1 package com.young.testserver.aidl;2 3 parcelable Person;
2. Create a server Service and return the implementation of the aidl interface through the onBind () method.
1 public class AidlRemoteService extends Service {2 3 // IRemoteData. the specific implementation of Stub 4 private class RemoteData extends IRemoteData. stub {5 int data; 6 Person person Person; 7 @ Override 8 public int getRemoteData () throws RemoteException {9 return data; 10} 11 12 @ Override13 public void setRemoteData (int data) throws RemoteException {14 this. data = data; 15} 16 17 @ Override18 public Person getPerson () throws RemoteException {19 return person; 20} 21 22 @ Override23 public void setPerson (Person person) throws RemoteException {24 this. person = person; 25} 26 27} 28 29 @ Override30 public IBinder onBind (Intent intent) {31 // IRemoteData to be implemented. stub class return, the client can use the asInterface provided by Stub to obtain 32 return new RemoteData (); 33} 34}
3. copy the aidl file and java file corresponding to the server to the client. when the client is bound to a service, use the asInterface provided by Stub to obtain the interface class implemented by the server, then, use the implemented interface class to call the functions in AIDL.
1 public class AidlClientActivity extends Activity {2 3 private static final String TAG = "-- DEBUG --"; 4 5 private static final String BIND_ACTION = "com. young. server. START_AIDL_SERVICE "; 6 private Button mBindBtn; 7 8 @ Override 9 protected void onCreate (Bundle savedInstanceState) {10 super. onCreate (savedInstanceState); 11 setContentView (R. layout. activity_aidl_client); 12 13 mBindBtn = (Button) findViewById (R. id. bind_service); 14 mBindBtn. setOnClickListener (new OnClickListener () {15 @ Override16 public void onClick (View v) {17 bindService (new Intent (BIND_ACTION), conn, Context. BIND_AUTO_CREATE); 18} 19}); 20} 21 22 private ServiceConnection conn = new ServiceConnection () {23 24 @ Override25 public void onServiceDisconnected (ComponentName name) {26 Log. v (TAG, "AIDL service disconnected"); 27} 28 29 @ Override30 public void onServiceConnected (ComponentName, IBinder service) {31 Log. v (TAG, "AIDL service linked"); 32 33 // get the server's implementation of Stub 34 IRemoteData remoteData = IRemoteData. stub. asInterface (service); 35 try {36 remoteData. setRemoteData (123456); 37 int data = remoteData. getRemoteData (); 38 Log. v (TAG, "client get remote data =" + data); 39 40 remoteData. setPerson (new Person ("Allen", 25); 41 Person person = remoteData. getPerson (); 42 Log. v (TAG, "client get remote Person =" + person. toString (); 43} catch (RemoteException e) {44 e. printStackTrace (); 45} 46} 47}; 48}
4. Passing objects between processes through AIDL must meet the following requirements:
(1) Implement the Parcelable interface.
(2) Implement the writeToParcel method to write the current object status to Parcel.
(3) Add a static variable named CREATOR to implement the Parcelable. Creator <T> interface.
(4) Create an AIDL file to declare this class (see the above Person. aidl)
1 public class Person implements Parcelable {2 3 private String name; 4 private int age; 5 6 public Person (String name, int age) {7 super (); 8 this. name = name; 9 this. age = age; 10} 11 12 public String getName () {13 return name; 14} 15 16 public void setName (String name) {17 this. name = name; 18} 19 20 public int getAge () {21 return age; 22} 23 24 public void setAge (int age) {25 this. age = age; 26} 27 28 @ Override29 public String toString () {30 return "Person [name =" + name + ", age =" + age + "]"; 31} 32 33 // ------------- split line --------------- 34 35 // read and write 36 public Person (Parcel parcel) {37 name = parcel. readString (); 38 age = parcel. readInt (); 39} 40 41 public static final Parcelable. creator <Person> CREATOR = new Parcelable. creator <Person> () {42 43 @ Override44 public Person createFromParcel (Parcel source) {45 return new Person (source ); 46} 47 48 @ Override49 public Person [] newArray (int size) {50 return new Person [size]; 51} 52 53}; 54 55 @ Override56 public int describeContents () {57 return 0; 58} 59 60 @ Override61 public void writeToParcel (Parcel dest, int flags) {62 dest. writeString (name); 63 dest. writeInt (age); 64}
Finally, run the program and print the following log results. The client obtains the data sent from the client to the server.
11-13 15:56:23. 081: V/-- DEBUG -- (25361): AIDL service linked
11-13 15:56:23. 081: V/-- DEBUG -- (25361): client get remote data = 123456
11-13 15:56:23. 081: V/-- DEBUG -- (25361): client get remote Person = Person [name = Allen, age = 25]