In-depth analysis of aidl principles

Source: Internet
Author: User
Tags mremote

In the previous article (service usage), we introduced the use of Android inter-process communication (IPC) and provided an example. However, we have not thoroughly analyzed how aidl can implement inter-process communication and how it executes?

This article analyzes the execution process of iremoteservice. aidl and understands how aidl communicates across processes.

 

When we create the iremoteservice. aidl file, IDE will create the corresponding file for us in the gen directory.

/** This file is auto-generated. do not modify. * Original file: F :\\ workspace \ androidimprove \ SRC \ com \ example \ aidl \ iremoteservice. aidl */package COM. example. aidl; public interface iremoteservice extends android. OS. iinterface {/** local-side IPC implementation stub class. */public static abstract class stub extends android. OS. binder implements COM. example. aidl. iremoteservice {private stati C Final Java. lang. string descriptor = "com. example. aidl. iremoteservice ";/** construct the stub at attach it to the interface. */Public stub () {This. attachinterface (this, descriptor);}/*** cast an ibinder object into an COM. example. aidl. iremoteservice interface, * generating a proxy if needed. */public static COM. example. aidl. iremoteservice asinterface (Android. OS. ibinder OBJ) {If (OBJ = NUL L) {return NULL;} Android. OS. iinterface Iin = (Android. OS. iinterface) obj. querylocalinterface (descriptor); If (IIN! = NULL) & (IIN instanceof COM. example. aidl. iremoteservice) {return (COM. example. aidl. iremoteservice) iIn);} return new COM. example. aidl. iremoteservice. stub. proxy (OBJ);} public android. OS. ibinder asbinder () {return this ;}@ override public Boolean ontransact (INT code, android. OS. parcel data, android. OS. parcel reply, int flags) throws android. OS. remoteException {Switch (CODE) {Case interface_tr Ansaction: {reply. writestring (descriptor); Return true;} case transaction_register: {data. enforceinterface (descriptor); COM. example. aidl. iremotecallback _ arg0; _ arg0 = com. example. aidl. iremotecallback. stub. asinterface (data. readstrongbinder (); this. register (_ arg0); reply. writenoexception (); Return true;} case transaction_unregister: {data. enforceinterface (descriptor); COM. example. aidl. iremote Callback _ arg0; _ arg0 = com. example. aidl. iremotecallback. stub. asinterface (data. readstrongbinder (); this. unregister (_ arg0); reply. writenoexception (); Return true;} case transaction_execute: {data. enforceinterface (descriptor); this.exe cute (); reply. writenoexception (); Return true;} case transaction_getstatus: {data. enforceinterface (descriptor); Java. lang. string _ arg0; _ arg0 = data. readstring (); Int _ result = This. getstatus (_ arg0); reply. writenoexception (); reply. writeint (_ result); Return true ;}} return Super. ontransact (Code, Data, reply, flags);} Private Static class proxy implements COM. example. aidl. iremoteservice {private android. OS. ibinder mremote; proxy (Android. OS. ibinder remote) {mremote = remote;} public android. OS. ibinder asbinder () {return mremote;} public Java. lang. stri Ng getinterfacedescriptor () {return descriptor;} // registers the callback public void register (COM. example. aidl. iremotecallback callback) throws android. OS. remoteException {android. OS. parcel _ DATA = android. OS. parcel. obtain (); android. OS. parcel _ reply = android. OS. parcel. obtain (); try {_ data. writeinterfacetoken (descriptor); _ data. writestrongbinder (callback! = NULL ))? (Callback. asbinder () :( null); mremote. transAct (stub. transaction_register, _ data, _ reply, 0); _ reply. readexception ();} finally {_ reply. recycle (); _ data. recycle () ;}}// cancel registration callback public void unregister (COM. example. aidl. iremotecallback callback) throws android. OS. remoteException {android. OS. parcel _ DATA = android. OS. parcel. obtain (); android. OS. parcel _ reply = android. OS. parcel. obtain (); try {_ DATA. Writeinterfacetoken (descriptor); _ data. writestrongbinder (callback! = NULL ))? (Callback. asbinder () :( null); mremote. transAct (stub. transaction_unregister, _ data, _ reply, 0); _ reply. readexception ();} finally {_ reply. recycle (); _ data. recycle () ;}}// execution callback public void execute () throws android. OS. remoteException {android. OS. parcel _ DATA = android. OS. parcel. obtain (); android. OS. parcel _ reply = android. OS. parcel. obtain (); try {_ data. writeinterfacetoken (descriptor); mremote. transAct (stub. transaction_execute, _ data, _ reply, 0); _ reply. readexception ();} finally {_ reply. recycle (); _ data. recycle () ;}// get the public int getstatus (Java. lang. string flag) throws android. OS. remoteException {android. OS. parcel _ DATA = android. OS. parcel. obtain (); android. OS. parcel _ reply = android. OS. parcel. obtain (); int _ result; try {_ data. writeinterfacetoken (descriptor); _ data. writestring (FLAG); mremote. transAct (stub. transaction_getstatus, _ data, _ reply, 0); _ reply. readexception (); _ result = _ reply. readint ();} finally {_ reply. recycle (); _ data. recycle ();} return _ result;} static final int transaction_register = (Android. OS. ibinder. first_call_transaction + 0); static final int transaction_unregister = (Android. OS. ibinder. first_call_transaction + 1); static final int transaction_execute = (Android. OS. ibinder. first_call_transaction + 2); static final int transaction_getstatus = (Android. OS. ibinder. first_call_transaction + 3);} // registration callback public void register (COM. example. aidl. iremotecallback callback) throws android. OS. remoteException; // cancel registration callback public void unregister (COM. example. aidl. iremotecallback callback) throws android. OS. remoteException; // execution callback public void execute () throws android. OS. remoteException; // get the public int getstatus (Java. lang. string flag) throws android. OS. remoteException ;}

When a clientactivity is bound to a remote service and a connection is established, serviceconnection. onserviceconnected (componentname, ibinder service) is called)

Public void onserviceconnected (componentname name, ibinder Service) {remoteservice = iremoteservice. stub. asinterface (service); // register the callback try {remoteservice. register (remotecallback);} catch (RemoteException e) {e. printstacktrace ();}}

The ibinder service is the iremoteservice. Stub ibinder returned from the remoteservice. This object is an object in the server application process.

Iremoteservice. stub. asinterface (service) creates a local proxy

 

Public static com. example. aidl. iremoteservice asinterface (Android. OS. ibinder OBJ)

{

If (OBJ = NULL )){

Return NULL;

}

Android. OS. iinterface Iin = (Android. OS. iinterface) obj. querylocalinterface (descriptor); // null is definitely returned here

If (IIN! = NULL) & (IIN instanceof com. example. aidl. iremoteservice ))){

Return (COM. example. aidl. iremoteservice) iIn );

}

Return new COM. example. aidl. iremoteservice. stub. Proxy (OBJ); // create a local proxy

}

 

 

When remoteservice is used to call a method, the local com. example. aidl. iremoteservice. stub. proxy object method. From the proxy method, we can see that each method executes mremote. transAct (stub. transaction_xxx, _ data, _ reply, 0 );.

For example:

// Obtain the public int getstatus (Java. lang. string flag) throws android. OS. remoteException {android. OS. parcel _ DATA = android. OS. parcel. obtain (); android. OS. parcel _ reply = android. OS. parcel. obtain (); int _ result; try {_ data. writeinterfacetoken (descriptor); _ data. writestring (FLAG); mremote. transAct (stub. transaction_getstatus, _ data, _ reply, 0); _ reply. readexception (); _ result = _ reply. readint ();} finally {_ reply. recycle (); _ data. recycle ();} return _ result ;}

In this process, the client parameters are converted to parcel (_ data) and passed to the server, while the server saves the returned data to _ reply, this forms an interaction.

Mremote is a remote object. The transact method executes the ontransact method.

public final boolean transact(int code, Parcel data, Parcel reply,              int flags) throws RemoteException {          if (Config.LOGV) Log.v("Binder", "Transact: " + code + " to " + this);          if (data != null) {              data.setDataPosition(0);          }          boolean r = onTransact(code, data, reply, flags);          if (reply != null) {              reply.setDataPosition(0);          }          return r;      }  

In this way, the remote ontransact method will be executed,

case TRANSACTION_getStatus:  {  data.enforceInterface(DESCRIPTOR);  java.lang.String _arg0;  _arg0 = data.readString();  int _result = this.getStatus(_arg0);  reply.writeNoException();  reply.writeInt(_result);  return true;  }  

Note int _ result = This. getstatus (_ arg0);, this calls the getstatus (string flag) on the server side, and writes the returned results to the _ Reply of the proxy object on the client side.

 

At this point, the aidl communication process is complete.

PS: aidl communication is a bit complicated, but it is not difficult to analyze it carefully.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.