An in-depth understanding of Android's internal process communication interface Aidl_android

Source: Internet
Author: User
Tags call back int size naming convention stub mremote

Significance:

Because each application process has its own independent process space, on the Android platform, a process usually does not access the memory space of another process, and we often need to boast process passing objects, we need to break the object into the operational object can understand the basic unit, and orderly through the process boundary.

Defined:

Aidl (Android Interface Definition Language) is an IDL language used to generate interprocess communication between two processes on an Android device (interprocess communication, IPC) The code. If you are in a process, such as an activity, to invoke an operation on another process (such as a service) object, you can use Aidl to generate serializable parameters.

Description and implementation process:

There is no difference between the Aidl interface and the normal Java interface, Only the extension is. aidl, stored in the SRC directory, if other applications require IPC, you also need to create the same aidl file in the SRC directory, after the creation, through the ADT tool, the project's Gen directory to generate the corresponding. java files.

There are several steps you need to implement to generally communicate between two processes

(1) Create a file with a. aidl extension under the Eclipse's Android directory, which is similar to the syntax of the Java-defined interface, but requires you to manually import the corresponding package name. (for example, you need to use the List collection, you need to import java.util.List;)

(2) If the Aidl file conforms to the specification, the ADT tool will help the compiler generate a corresponding. java file in the Gen directory.

(3) need to inherit the implementation of a service class, the basis of the call across the process.

(4) Implement the Aidl interface at the service end and implement the callback Aidl interface on the client side if there is a callback.

(5) Register service in Androidmanifest.xml.

Attention:

To achieve aidl, we need to pay attention to the following five points

(1) Aidl only supports interface methods and cannot expose static variables.

(2) Aidl interface method if there are parameters, you need to pay attention to the use of in, out, inout rules, for the basic data type, the default is in type, you can not need to add a declaration, a non-basic variable object needs to add a method type before the variable name

In represents an input parameter that the caller passes the value to the user for use.

Out represents an output parameter that the caller passes the container to the consumer population, and then uses the processing itself.

InOut bid Input Output parameter, transmit corresponding value and receive return.

List an Out use example:
Service-side pass parameters to the client, client-side padding, the server end of the call, you can read to the client filled out the content, the specific example will be given later.

(3) The interface name defined by Aidl must be the same as the file name.

(4) OneWay indicates that the user requests the corresponding function without waiting for the response to call back directly, non-blocking effect, which can be used to declare an interface or declare a method, and if the OneWay keyword is used in the interface declaration, all the methods declared by the interface are oneway.

(5) Aidl Transfer of non-basic variable length variable (not final object), the need to implement Parcelable interface.
Parcel are generally used in binder communication, the read and write methods for client and server data transfer (communication).
For example: Frameworks layer server and hardware client binder communication

Reply->writeint32 (Getcardreadersize ());
int mid = Data.readint32 ();

For storing parcel data is memory (RAM), not permanent media (NAND, etc.).

Parcelable defines an interface that writes data to parcel and reads data from parcel, an instance of a class that, if needed to be encapsulated in a message, must implement this interface and, if implemented, an instance of that class can be "packaged".
Parcelabel implementation, you need to add a static member variable CREATOR to the class, which needs to inherit the Parcelable.creator interface.

Package com.zlc.provider;
Import Android.os.Parcel;
 
Import android.os.Parcelable;
  public class Students implements parcelable{private int stu_id;
  Private String Stu_name;
    Public Students (Parcel source) {stu_id = Source.readint ();
  Stu_name = Source.readstring ();
  public int getstu_id () {return stu_id;
  The public void setstu_id (int stu_id) {this.stu_id = stu_id;
  Public String Getstu_name () {return stu_name;
  } public void Setstu_name (String stu_name) {this.stu_name = Stu_name;
  @Override public int describecontents () {//TODO auto-generated method stub return 0; @Override public void Writetoparcel (Parcel dest, int flags) {//TODO auto-generated a stub Dest.writei
    NT (STU_ID);
  Dest.writestring (Stu_name); //interface that must is implemented and provided as a public CREATOR field that generates instances of your 
  E class from a Parcel. Public final static Parcelable.creator<students> CREATOR = new parcelable.creator<students> () {@Override public Students createfromparcel (Parc
    El Source) {//TODO auto-generated method stub return new Students (source); @Override public students[] NewArray (int size) {//TODO auto-generated method stub return new Stu
    Dents[size];
}
  };

 }


Example:

Here is an example the main implementation of the client call server and then callback back, the specific implementation of the function to change the client text and picture display, this example of the temporary effect is the picture of the changes directly using the client has been prepared pictures, the next few blog will be based on this function, to reach the server can send text, pictures File handle (I/O stream), and directly by the server side by the method name directly invoke the client method, the client only needs to register the corresponding view and provide the appropriate method for the server to use, The following two improvements are implemented primarily with reflection and rewrite memoryfile (to achieve the parcelable serialization effect).

(1) First in accordance with our previous steps need to create aidl files, respectively, to create calls and callbacks Aidl files, in order to elaborate a little bit of parcelable object also added, just as a test.
Imyaidlservice.aidl client-side calls are implemented primarily by the server

Package com.zlc.aidl;
Import com.zlc.aidl.DemoParcelable;
Import Com.zlc.aidl.AIDLCallback;
Interface imyaidlservice{
  void Registerclient (Aidlcallback cb);//Registration callback
  void Savedemoinfo (in demoparcelable demo);//Actual Call Method
}

Aidlcallback.aidl is implemented primarily by the client, and the server calls

Package com.zlc.aidl;
Import com.zlc.aidl.DemoParcelable;
Import java.util.List;
Interface Aidlcallback {
  int returnresult (out list<demoparcelable> list,int a);/callback to client
  void TestMethod (out Bundle params);//used to test the use of the parameter In/out
}

Demoparcelable.aidl Declaration Delivery Object:

Package com.zlc.aidl;
Parcelable demoparcelable;

Add: Out and in parameter differences in fact, it is obvious that we look directly at the ADT generate the corresponding Java files in the Gen directory to see the difference: When the out parameter is performed, the value is read from the parcel object, and in the parameter is written to the parcel object inside the pass.
Let's look at the file generated when TestMethod is out and in decorated, respectively.
When it was out, I read the data from the parcel object.

Mremote.transact (Stub.transaction_testmethod, _data, _reply, 0);
_reply.readexception ();
if ((0!=_reply.readint ())) {
params.readfromparcel (_reply);
}

When in, I took the data from the parcel object.

if ((Params!=null)) {
_data.writeint (1);
Params.writetoparcel (_data, 0);
}
else {
_data.writeint (0);
}
Mremote.transact (Stub.transaction_testmethod, _data, _reply, 0);
_reply.readexception ();

(2) Implement a service class used to implement communication between processes Myaidlservice.java, posted part of the code, detailed code will be uploaded later.

@Override public IBinder onbind (Intent Intent) {//TODO auto-generated Method Stub log.d (TAG, "Myaidlservice o
    Nbind ");
  return mbinder;
 
    Private final Imyaidlservice.stub Mbinder = new Imyaidlservice.stub () {private Aidlcallback CB; @Override public void Savedemoinfo (Demoparcelable demo) throws RemoteException {if (demo!= null) {if ("Meinv1". Equals (Demo.getdemo_name ()))
        {Demo.setdemo_name ("meinv2");
        List.add (demo);
        LOG.D (TAG, "savedemoinfo list.size =" + list.size () + "list =" + list);
        Cb.returnresult (list, 5);
        Bundle params = new Bundle ();
        Cb.testmethod (params);
        int width = params.getint ("width", 0);
        int height = params.getint ("height", 0);
      LOG.D (TAG, "width =" + width + "height =" +height); @Override public void Registerclient (Aidlcallback cb) throws RemoteException {Cb.asbinder (). Linkt Odeath (New Deathrecipient ({@Override public void binderdied () {try {log.i (TAG, "[Serviceaidlimpl]binderdi
    ed. "); \ catch (Throwable e) {}}}, 0);
 }
  };

   
(3) implements the client connection and implements the callback method  

Private Serviceconnection mremoteconnection = new Serviceconnection () {@Override public void Onservicedisconne
    CTED (componentname name) {//TODO auto-generated Method Stub log.d (TAG, "onservicedisconnected"); @Override public void onserviceconnected (componentname name, IBinder service) {//TODO auto-generated m
      Ethod stub log.d (TAG, "onserviceconnected");
      Mremoteservice = (imyaidlservice) imyaidlservice.stub. Asinterface (service);
    if (mremoteservice!= null) LOG.D (TAG, "onserviceconnected success");
}
  }; ... btn.setonclicklistener (new Onclicklistener () {@Override public void OnClick (View v) {//TODO Au
        to-generated method Stub String actionname = "Com.zlc.aidl.server.MyAidlService";
        Intent Intent = new Intent (actionname);
        boolean ret = Bindservice (Intent, mremoteconnection, context.bind_auto_create);
      LOG.D (TAG, "ret =" + ret);  if (ret) {new Thread (new Runnable () {@Override public void run () {/
                /TODO auto-generated Method stub try {demoparcelable demo = new Demoparcelable ();
                list<string> list = new arraylist<string> ();
                List.add ("Like Dance");
                DEMO.SETDEMO_ID ((Integer) Img.gettag ());
                Demo.setdemo_name ("Meinv1");
                Demo.setdemo_list (list);
                Mremoteservice.registerclient (callback);
              Mremoteservice.savedemoinfo (demo);
              catch (Exception e) {//TODO auto-generated catch block E.printstacktrace ();
 
        }}). Start ();
  }
      }
    }); ... private final Aidlcallback callback = new Aidlcallback.stub () {@Override public int returnresult (Lis
t<demoparcelable> list, int a) throws RemoteException {      if (list!= null) LOG.D (TAG, "list.size =" + list.size () + "a=" +a);
      for (demoparcelable demoparcelable:list) {Dofresh (demoparcelable);
    return 0; @Override public void TestMethod (Bundle outparams) throws RemoteException {//TODO auto-generated Metho
        D stub if (outparams!= null) {outparams.putint ("width", 11);
      Outparams.putint ("height", 12);
 }
 
    }
  };


(4) Register service in Androidmanifest.xml.
Note: android:process= ": Remote", which represents that in an application, a new process is automatically created when the service is needed. If it is android:process= "remote" and does not have a ":" Semicolon, the global process is created, and the process is shared by different applications.
Through the PS directly to see the PID process number can be seen.
Let the applied component run in a separate process, if with a colon: Create a process that belongs to the current process and, without a colon, use the standard naming convention to name the process name. such as Com.xxx.xxx.xxx, and the process is a globally shared process, where components of different applications can run on that process.
This can break the application's 24M (or 16M) memory limit.
In summary, the parent process ID Ppid is the same, depending on the process ID pid of the attribute with: remote. Remote with no colon creates two completely separate processes.

Related Article

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.