On binder mechanism

Source: Internet
Author: User
Tags mremote

Some time ago have been looking at the knowledge of binder, recently just have time, summed up some knowledge, hope and everyone exchange study.

Speaking of Binder I believe that you learn more and more about the development of Android, the binder mechanism as a mechanism of communication between Android, the application of the Android bottom is very much. We all know that the Android system is based on the Linux kernel, and the Linux kernel provides a rich mechanism for interprocess communication, such as pipelines, signals, message queues, shared memory and sockets, but the Android system does not use the traditional interprocess communication mechanism. Instead of developing a new set of interprocess communication mechanisms binder, there are certainly some advantages to using binder, and the binder process communication mechanism can only perform one copy operation when transferring data between processes compared to traditional interprocess communication, so there are some advantages in efficiency and memory savings.

And then we're going to talk about binder, Binder is a class in Android, it implements the IBinder interface, from the android-framework point of view, Binder is a bridge for ServiceManager to connect various managers (Activitymanager, WindowManager, etc.) and corresponding manager_service; here's a picture of them.



Binder when communicating between processes, each server process and client process maintains a binder thread pool to handle inter-process communication requirements, and the service component registers itself in a Service Manager component at startup. So that the client component can find it through the Service Manager component. The binder driver and service Manager are provided by the system, the client and service are implemented by the application, and then I have a discussion of the most commonly used aidl in Android for example

Writing a AIDL program requires the following steps:


First, let's look at the steps required by the service-side program:

(1) First Write your class (Book.java) file, this class must implement the Parcelable interface to serialize.

(2) write the Aidl file (book.aidl) with the same name as the class

(3) Writing the interface file (IBOOKMANAGER.AIDL), which is the interface of the client when requested

(4) Implement service (Bookmanagerservice) on the server, which serves the client in real-time (mainly implements stub class)


Next, let's look at the steps the client will implement:

The client is actually similar to many places on the server side:

(1) We need to copy all aidl files from the server to the client, the registration must be consistent with the server, because of serialization and deserialization problems

(2) Write client activity, BIND Server service

(3) Implement Serviceconnection, in the Onserviceconnected method, convert the IBinder to the Aidl interface type, and then invoke the remote service

(4) If the remote service is time consuming, you can detach the calling method from the main thread and open a sub-thread so that the program does not crash


Well, everyone is now estimated to be very confused, I will give you again and then on the code:

First you can see, when we create a new Aidl file, in the Gen folder will generate a corresponding aidl file, he is the system for us automatically generated an interface class, Inherit from Android.os.IInterface interface, there are several more important classes and methods here I will explain to you:

First is the stub class, this stub class inherits the binder implementation of our defined Aidl interface, this class is our client in the actual use of the class, in this class has a Asinterface method, his parameter is a IBinder interface, He returned to another stub of the internal class proxy, the proxy class really implemented the Aidl interface, whenever the client through the stub Asinterface method to get to the class, invoke the specific interface method, the proxy class will call Transact, When both the client and the server are located in a process, the method call will not go through the process of the Transact process, if not the same process will be given to proxy processing, here Transact has a few parameters the first parameter is the requested method type, next _data and _ Reply They are both a parcel type, which encapsulates the client's request information and the service-side feedback information, and then the underlying transmission through Bindler to the Ontransact method, he will be passed from the client parameters to determine the client request is the method, What the request information is, then writes the data to the client.

Above is the entire process of binder cross-process, the following is the code:


Aidl file

Book.javapackage Com.binderpro.aidl;import Android.os.parcel;import android.os.parcelable;public class book Implements Parcelable{private string name;private int price;private int bookid;public string getName () {return name;} public void SetName (String name) {this.name = name;} public int GetPrice () {return price;} public void Setprice (int. price) {this.price = Price;} Public book (String name, int price) {super (); this.name = Name;this.price = Price;} @Overridepublic String toString () {return "book [name=" + name + ", price=" + Price + "]";} @Overridepublic int describecontents () {//TODO auto-generated method Stubreturn 0;} @Overridepublic void Writetoparcel (Parcel arg0, int arg1) {//TODO auto-generated method Stubarg0.writeint (bookId); Arg0.writestring (name); Arg0.writeint (price);} public static final parcelable.creator<book> Creator = new parcelable.creator<book> () {@Overridepublic book Createfromparcel (Parcel arg0) {//TODO auto-generated method Stubreturn new book (arg0);} @OverridePublic book[] NewArray (int arg0) {//TODO auto-generated method Stubreturn new book[arg0];}; Private book (Parcel in) {bookId = In.readint (); name = In.readstring ();p rice = In.readint ();}}
Book.aidlpackage com.binderpro.aidl;parcelable Book;

Ibookmanager

Package Com.binderpro.aidl;import Java.util.list;import com.binderpro.aidl.book;interface IBookManager {List< Book> getbooklist (); void Addbook (in book book);}

Bookmanagerservice

Package Com.example.binderpro;import Java.util.list;import Java.util.concurrent.copyonwritearraylist;import Android.app.service;import Android.content.intent;import Android.os.binder;import Android.os.IBinder;import Android.os.remoteexception;import Com.binderpro.aidl.book;import Com.binderpro.aidl.ibookmanager;public Class Bookmanagerservice extends Service {private static final String TAG = "BMS";p rivate copyonwritearraylist<book> Mboo Klist = new copyonwritearraylist<book> ();p ublic Bookmanagerservice () {//TODO auto-generated constructor stub} Private Binder Mbinder = new Ibookmanager.stub () {@Overridepublic list<book> getbooklist () throws RemoteException { TODO auto-generated method Stubreturn mbooklist;} @Overridepublic void Addbook throws RemoteException {//TODO auto-generated Method Stubmbooklist.add (book);}; @Overridepublic void OnCreate () {//TODO auto-generated method Stubsuper.oncreate (); Mbooklist.add ("Android", 1 )); Mbooklist.add (New BoOk ("ios", 2));} Public IBinder Onbind (Intent Intent) {return mbinder;}}

Next is the client code, aidl file ibid.

Mainactivity.java

Package Com.example.binderpro;import Java.util.list;import Com.binderpro.aidl.book;import Com.binderpro.aidl.ibookmanager;import Android.os.bundle;import Android.os.ibinder;import Android.os.remoteexception;import Android.app.activity;import Android.content.componentname;import Android.content.context;import Android.content.intent;import Android.content.serviceconnection;import Android.util.log;import Android.view.menu;public class Mainactivity extends Activity {private serviceconnection Mconnection = new Serviceconnection () {@Overridepublic void onservicedisconnected (ComponentName arg0) {//TODO auto-generated method stub} @Overridepublic void Onserviceconnected (componentname arg0, IBinder arg1) {//TODO Auto-generated method Stubibookmanager Bookmanager = IBookManager.Stub.asInterface (arg1); list<book> list;try {list = Bookmanager.getbooklist (); LOG.I ("Tag", list.tostring ());} catch (RemoteException e) {//TODO auto-generated catch Blocke.printstacktrace ();}}; protected void OncreAte (Bundle savedinstancestate) {super.oncreate (savedinstancestate); Setcontentview (r.layout.activity_main); Intent Intent = new Intent ("Com.example.binderpro.BookManagerService"); Bindservice (Intent, mconnection, context.bind_auto_ CREATE);} @Overrideprotected void OnDestroy () {//TODO auto-generated method Stubsuper.ondestroy (); Unbindservice (mconnection);}}

Finally, the system generates Java code according to the Aidl file;

Ibookmanager code is long, I deleted a part

/* * This file is auto-generated. Do not MODIFY. * Original File:g:\\android_code\\binderpro\\src\\com\\binderpro\\aidl\\ibookmanager.aidl */package Com.binderpro.aidl;public interface Ibookmanager extends Android.os.IInterface {/** local-side IPC implementation stub Class. */public static abstract class Stub extends Android.os.Binder implementscom.binderpro.aidl.IBookManager {private static Final java.lang.String descriptor = "Com.binderpro.aidl.IBookManager";/** Construct the stub at attach it to the interface . */public Stub () {this.attachinterface (this, descriptor);} /** * Cast an IBinder object to an com.binderpro.aidl.IBookManager * interface, generating a proxy if needed. */public static Com.binderpro.aidl.IBookManager asinterface (Android.os.IBinder obj) {if ((obj = = null)) {return null;} Android.os.IInterface iin = obj.querylocalinterface (descriptor); if ((iin! = null) && (iin instanceof Com.binderpro.aidl.IBookManager)) {return (Com.binderpro.aidl.IBookManager) iin);} return new Com.binderpro.aidl.IBookManager.Stub.Proxy (obj); @Overridepublic Android.os.IBinder Asbinder () {return this;} @Overridepublic boolean ontransact (int code, android.os.Parcel data,android.os.parcel reply, int flags) throws android.os.RemoteException {switch (code) {case Interface_transaction: {reply.writestring (descriptor); return true;} Case Transaction_getbooklist: {data.enforceinterface (descriptor);java.util.list<com.binderpro.aidl.book> _ result = This.getbooklist (); Reply.writenoexception (); reply.writetypedlist (_result); return true;} Case Transaction_addbook: {data.enforceinterface (descriptor); Com.binderpro.aidl.Book _arg0;if ((0! = Data.readint ()) {_arg0 = com.binderpro.aidl.Book.CREATOR.createFromParcel (data);} else {_arg0 = null;} This.addbook (_arg0); reply.writenoexception (); return true;}} Return Super.ontransact (Code, data, reply, flags);} private static class Proxy implements Com.binderpro.aidl.IBookManager {private Android.os.IBinder mremote;@ Overridepublic Java.util. List<com.binderpro.aidl.book> getbooklist () throws android.os.RemoteException {Android.os.Parcel _data = Android.os.Parcel.obtain (); Android.os.Parcel _reply = Android.os.Parcel.obtain ();java.util.list< Com.binderpro.aidl.book> _result;try {_data.writeinterfacetoken (descriptor); Mremote.transact (Stub.TRANSACTION _getbooklist, _data,_reply, 0); _reply.readexception (); _result = _reply.createtypedarraylist ( Com.binderpro.aidl.Book.CREATOR);} finally {_reply.recycle (); _data.recycle ();} return _result;} @Overridepublic void Addbook (Com.binderpro.aidl.Book book) throws Android.os.RemoteException {Android.os.Parcel _data = Android.os.Parcel.obtain (); Android.os.Parcel _reply = Android.os.Parcel.obtain (); try {_data.writeinterfacetoken ( Descriptor), if ((book! = null)) {_data.writeint (1); Book.writetoparcel (_data, 0);} else {_data.writeint (0);} Mremote.transact (Stub.transaction_addbook, _data, _reply, 0); _reply.readexception ();} finally {_reply.recycle (); _data.recycle ();}}} static final int TransaCtion_getbooklist = (Android.os.IBinder.FIRST_CALL_TRANSACTION + 0); static final int transaction_addbook = ( Android.os.IBinder.FIRST_CALL_TRANSACTION + 1);}}

so much for today, I've been working on the bottom of the binder lately, and I might feel like I'm going to be able to write something about the bottom of the binder, because the binder is too complicated, and the Linux driver layer is C code, At the bottom are a lot of structure and some red and black trees, hash table, reference chain organization, some of the binder thread pool, synchronization, buffer, Death Notification Association is very complex, interested can see Luo Shenyang "Android system source Scenario analysis" This book is very good for the binder underlying mechanism.




On binder mechanism

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.