相关源码路径

/framework/base/core/java/Android/os/IInterface.java/framework/base/core/java/Android/os/IServiceManager.java/framework/base/core/java/Android/os/ServiceManager.java/framework/base/core/java/Android/os/ServiceManagerNative.java(包含内部类ServiceManagerProxy)/framework/base/core/java/Android/os/IBinder.java/framework/base/core/java/Android/os/Binder.java(包含内部类BinderProxy)/framework/base/core/java/Android/os/Parcel.java/framework/base/core/java/com/Android/internal/os/BinderInternal.java/framework/base/core/jni/Android_os_Parcel.cpp/framework/base/core/jni/AndroidRuntime.cpp/framework/base/core/jni/Android_util_Binder.cpp

       Android系统中,多进程间的通信都是依赖于底层Binder IPC机制,Binder机制是一种RPC方案例如:当进程A中的Activity与进程B中的Service通信时,就使用了binder机制。为了完成进程间的通信,binder使用AIDL来描述进程间的接口。此外,整个Android系统架构中,采用了大量的binder机制。

       Android中的Binder通信采用C/S架构,从组件视角来说,包含ClientServerService Manager以及binder驱动,其中Service Manager用于管理系统中的各种服务。Binder整体通信架构如下图所示:

 

(1)注册服务(addService):Server进程要先注册Service到Service Manager。该过程:Server是客户端,Service Manager是服务端;

(2)获取服务(getService):Client进程使用某个Service前,须先向Service Manager中获取相应的Service。该过程:Client是客户端,Service Manager是服务端;

(3)使用服务:Client根据得到的Service信息建立与Service所在的Server进程通信的通路,然后就可以直接与Service交互。该过程:client是客户端,server是服务端。

       

        binder相对来说还是比较复杂的,有framework层与native层的binder。framework层的binder采用JNI技术来调用native(C/C++ framework)层的binder架构,从而为上层应用程序提供服务。需要注意的是:

(1) framework层的Binder是建立在Native层架构基础之上的,核心逻辑都是交予Native层方法来处理

(2)framework层的Service Manager类与Native层的功能并不完全对应,java层的Service Manager类的实现最终是通过BinderProxy传递给Native层来完成的。

 

       图中红色代表整个frameworkbinder架构相关组件;Binder类代表Server端,BinderProxy类代表Client端;图中蓝色代表NativeBinder架构相关组件。


1 binder介绍

         Android源码中,binder的核心库是在native层实现,但在java层和native层都有接口供应用程序使用。如果单从binder角度出发,Binder架构图如下:

 

(1) binder驱动层

         Android因此添加了binder驱动,其设备节点为/dev/binder,主设备号为10binder驱动程序在内核中的头文件和代码路径如下:

   kernel/drivers/staging/binder.h

         kernel/drivers/staging/binder.c

         binder驱动层的主要作用是完成实际的binder数据传输。

(2) binder adapter

       主要是IPCThreadState.cppProcessState.cpp,源码位于frameworks/native/libs/binder目录下,这两个类都采用了单例模式,主要负责和驱动直接交互。

        a、ProcessState,进程相关的类,负责打开binder设备,进行一些初始化设置并做内存映射;

void ProcessState::startThreadPool()该方法启动的新线程,并通过joinThreadPool读取binder设备,查看是否有请求。

        b、IPCThreadState,线程相关的类,负责直接和binder设备通信,使用ioctl读写binder驱动数据。 

status_t IPCThreadState::talkWithDriver(bool doReceive) 该方法调用的是ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)从/dev/binder读取。status_t IPCThreadState::executeCommand(int32_t cmd)该方法是对talkWithDriver返回的数据进行处理。void IPCThreadState::joinThreadPool(bool isMain)该方法创建线程并进行talkWithDriver以及executeCommand。

(3) Binder核心层

       Binder核心层主要是IBinder及它的两个子类,即BBinderBpBinder,分别代表了最基本的服务端及客户端。源码位于frameworks/native/libs/binder目录下。

       binder service服务端实体类会继承BnInterface,而BnInterface会继承自BBinder,服务端可将BBinder对象注册到servicemananger进程。

       客户端程序和驱动交互时只能得到远程对象的句柄handle,它可以调用调用ProcessStategetStrongProxyForHandle函数,利用句柄handle建立BpBinder对象,然后将它转为IBinder指针返回给调用者。这样客户端每次调用IBinder指针的transact方法,其实是执行BpBindertransact方法。

(4) Binder框架层

      a、Native Binder框架层包含以下类(frameworks/native/libs/binder)IInterfaceBnInterfaceBpInterface,等。

      b、Java框架层包含以下类(frameworks/base/core/java/android/os):

      IBinderBinderIInterfaceServiceManagerNativeServiceManagerBinderInternalIServiceManagerServiceManagerProxy

     Java框架层的类的部分方法的实现在本地代码里(frameworks/base/core/jni)


1.1 Binder类分层

        整个Binderkernel至,nativeJNIFramework层所涉及的类如下:

【初始化】

         Zygote启动时会有一个虚拟机注册过程,该过程调用AndroidRuntime::startReg方法来完成jni方法的注册。调用register_Android_os_Binder完成binder的native方法注册。
int register_Android_os_Binder(JNIEnv* env){    // 注册Binder类的jni方法    if (int_register_Android_os_Binder(env) < 0)          return -1;    // 注册BinderInternal类的jni方法    if (int_register_Android_os_BinderInternal(env) < 0)        return -1;    // 注册BinderProxy类的jni方法    if (int_register_Android_os_BinderProxy(env) < 0)        return -1;                  ...    return 0;}


1.2 binder调用顺序

          使用AIDL进行跨进程的通信,实际上就是使用binder,必须要继承binder接口,java和C++都有对应的IBinder,proxy,stub等,通过jni进程数据的交互,binder的核心在native层。整个调用关系如下。



2 Binder的Proxy-Stub模式


2.1 Java空间      


        IBinder/Binder/BinderProxy是Binder机制的核心api, 而IInterface和AIDL就是为了方便开发者使用Binder进行进程间通信。先看IBinder接口:
public interface IBinder {    . . . . . .    public String getInterfaceDescriptor() throws RemoteException;    public boolean pingBinder();    public boolean isBinderAlive();    public IInterface queryLocalInterface(String descriptor);  //返回IInterface类型    public void dump(FileDescriptor fd, String[] args) throws RemoteException;    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException;  //通信函数        public interface DeathRecipient     {        public void binderDied();    }    public void linkToDeath(DeathRecipient recipient, int flags)throws RemoteException;    public boolean unlinkToDeath(DeathRecipient recipient, int flags);}

Binder与BinderProxy的定义如下,都实现了IBinder接口
public class Binder implements IBinder {    ...    public Binder() {        init();        if (FIND_POTENTIAL_LEAKS) {            final Class<? extends Binder> klass = getClass();            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&                    (klass.getModifiers() & Modifier.STATIC) == 0) {                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +                    klass.getCanonicalName());            }        }    }        public void attachInterface(IInterface owner, String descriptor) {        mOwner = owner;        mDescriptor = descriptor;    }        public String getInterfaceDescriptor() {        return mDescriptor;    }    public IInterface queryLocalInterface(String descriptor) {        if (mDescriptor.equals(descriptor)) {            return mOwner;        }        return null;    }    protected boolean onTransact(int code, Parcel data, Parcel reply,            int flags) throws RemoteException {        if (code == INTERFACE_TRANSACTION) {            reply.writeString(getInterfaceDescriptor());            return true;        } else if (code == DUMP_TRANSACTION) {            ParcelFileDescriptor fd = data.readFileDescriptor();            String[] args = data.readStringArray();            if (fd != null) {                try {                    dump(fd.getFileDescriptor(), args);                } finally {                    try {                        fd.close();                    } catch (IOException e) {                        // swallowed, not propagated back to the caller                    }                }            }            // Write the StrictMode header.            if (reply != null) {                reply.writeNoException();            } else {                StrictMode.clearGatheredViolations();            }            return true;        }        return false;    }        public final boolean transact(int code, Parcel data, Parcel reply,            int flags) throws RemoteException {        if (false) Log.v("Binder", "Transact: " + code + " to " + this);        if (data != null) {            data.setDataPosition(0);        }        boolean r = onTransact(code, data, reply, flags);//调用onTransact()函数        if (reply != null) {            reply.setDataPosition(0);        }        return r;    }        public void linkToDeath(DeathRecipient recipient, int flags) {    }    public boolean unlinkToDeath(DeathRecipient recipient, int flags) {        return true;    }        protected void finalize() throws Throwable {        try {            destroy();        } finally {            super.finalize();        }    }    private native final void init();    private native final void destroy();    // Entry point from android_util_Binder.cpp's onTransact    private boolean execTransact(int code, long dataObj, long replyObj, int flags) {        ...        try {            res = onTransact(code, data, reply, flags);//调用onTransact()函数        } catch (RemoteException e) {            if ((flags & FLAG_ONEWAY) != 0) {                Log.w(TAG, "Binder call failed.", e);            } else {                reply.setDataPosition(0);                reply.writeException(e);            }            res = true;        }         ...        return res;    }}final class BinderProxy implements IBinder {    ...    public IInterface queryLocalInterface(String descriptor) {        return null;    }    public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");        return transactNative(code, data, reply, flags);    }    public native String getInterfaceDescriptor() throws RemoteException;    public native boolean transactNative(int code, Parcel data, Parcel reply,            int flags) throws RemoteException;    public native void linkToDeath(DeathRecipient recipient, int flags)            throws RemoteException;    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);    BinderProxy() {        mSelf = new WeakReference(this);    }       ...}
最后,在来看IInterface接口,很简单,就一个方法,返回值是IBinder。
public interface IInterface{    public IBinder asBinder();}
四者的UML类图如下所示:

       这就是BInder机制Proxy-Stub模式原始配方。        在这个类图的最顶层,有两个接口,IInterface和IBinder。IBinder代表跨进程传输的能力,而IInterface则用来辅助实现具体的传输业务。Binder是IBinder的实现类,因此它具备跨进程传输的能力,它实际上就是远程Server端的Binder对象本身。与此对应的BinderProxy则是远程Binder的代理对象,给Client进程用的。在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。

当我们写了一个AIDL文件之后,如下:
interface ICompute {    int add(int a,int b);}
此时,会生成一个相应的java文件,如下:
/* * This file is auto-generated.  DO NOT MODIFY. * Original file: D:\\Code\\Github\\Android\\Demo\\src\\com\\tfygg\\demo\\service\\ICompute.aidl */package com.tfygg.demo.service;public interface ICompute extends android.os.IInterface {/** Local-side IPC implementation stub class. */public static abstract class Stub extends android.os.Binder implements com.tfygg.demo.service.ICompute {private static final java.lang.String DESCRIPTOR = "com.tfygg.demo.service.ICompute";/** Construct the stub at attach it to the interface. */public Stub() {this.attachInterface(this, DESCRIPTOR);}/** * Cast an IBinder object into an com.tfygg.demo.service.ICompute * interface, generating a proxy if needed. */public static com.tfygg.demo.service.ICompute asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.tfygg.demo.service.ICompute))) {return ((com.tfygg.demo.service.ICompute) iin);}return new com.tfygg.demo.service.ICompute.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_add: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();int _arg1;_arg1 = data.readInt();int _result = this.add(_arg0, _arg1);reply.writeNoException();reply.writeInt(_result);return true;}}return super.onTransact(code, data, reply, flags);}private static class Proxy implements com.tfygg.demo.service.ICompute {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}@Overridepublic int add(int a, int b) 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.writeInt(a);_data.writeInt(b);mRemote.transact(Stub.TRANSACTION_add, _data, _reply, 0);_reply.readException();_result = _reply.readInt();} finally {_reply.recycle();_data.recycle();}return _result;}}static final int TRANSACTION_add = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public int add(int a, int b) throws android.os.RemoteException;}
对照着生成出来的ICompute.java文件,绘制如下Binder模型图:

     上图中绿色部分就是生成的java文件的内容,我们发现AIDL的Binder模型是基于原始配方的扩展。当我们写完ICompute.aidl之后,ICompute,Stub,Proxy已经自动生成出来,其作用如下:
(1)ICompute接口继承了IInterface,并写了add(a,b)的方法,代表Server端进程具备计算两数相加的能力。此方法将在Stub的具体实现类中重写。
(2)Stub是一个抽象类,他本质是一个Binder,他存在的目的之一是约定好asInterface,asBinder,onTransact方法,减少我们开发具体Binder对象的工作量。此外,Stub即需要跨进程传输,又需要约定远端服务端具备的能力,因此他需要同时实现IInterface和IBinder接口,通过上文的类图可以看得出来。
(3)Proxy是代理对象,它在Client进程中使用,它持有BinderProxy对象,BinderProxy能帮我们访问服务端Binder对象的能力。

2.1 C空间

       在C空间中,仍然是一样的Binder配方,不同的是,C空间没有了AIDL,而是使用模板辅助实现了Proxy-stub。所以,在C空间中也有IBinder.h,Binder。UML类图如下:

      先看IBinder,其定义截选如下:
class IBinder : public virtual RefBase{public:    . . . . . .    IBinder();    virtual sp  queryLocalInterface(const String16& descriptor);    virtual const String16& getInterfaceDescriptor() const = 0;    virtual bool            isBinderAlive() const = 0;    virtual status_t        pingBinder() = 0;    virtual status_t        dump(int fd, const Vector& args) = 0;    virtual status_t        transact(uint32_t code, const Parcel& data,                                     Parcel* reply, uint32_t flags = 0) = 0;    class DeathRecipient : public virtual RefBase    {    public:        virtual void binderDied(const wp& who) = 0;    };    virtual status_t        linkToDeath(const sp& recipient,                                        void* cookie = NULL, uint32_t flags = 0) = 0;    virtual status_t        unlinkToDeath(const wp& recipient,                                          void* cookie = NULL, uint32_t flags = 0,                                          wp* outRecipient = NULL) = 0;    virtual bool            checkSubclass(const void* subclassID) const;        typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);    virtual void            attachObject(const void* objectID, void* object,                                         void* cleanupCookie, object_cleanup_func func) = 0;    virtual void*           findObject(const void* objectID) const = 0;    virtual void            detachObject(const void* objectID) = 0;    virtual BBinder*        localBinder();    virtual BpBinder*       remoteBinder();protected:    virtual          ~IBinder();private:};
有接口必然有实现,BBinder和BpBinder都是IBinder的实现类,这里就总结一下他们的区别:

(1)pingBinder, BBinder直接返回OK,而BpBinder需要运行一个transact函数,这个函数很重要。
(2)linkToDeath()是用来在服务挂的时候通知客户端的,那服务端当然不需要自己监视自己咯,所以BBinder直接返回非法,而Bpbinder需要通过requestDeathNotification()要求某人完成这个事情。

        奇怪的是BBinder和BpBinder都没有实现queryLocalInterface() 接口啊,那肯定另有他人实现这个类了,这个人就是IInterface.h。客户程序通过queryLocalInterface() 可以知道服务端都提供哪些服务。        在IInterface.h中定义的BnInterface和BpInterface是两个重要的模版,这是为各种程序中使用的。
template  class BnInterface : public INTERFACE, public BBinder  {  public:      virtual sp  queryLocalInterface(const String16& _descriptor);      virtual String16        getInterfaceDescriptor() const;  protected:      virtual IBinder*        onAsBinder();  };       BnInterface模版的定义如下所示:  template  class BpInterface : public INTERFACE, public BpRefBase  {  public:                              BpInterface(const sp& remote);  protected:      virtual IBinder*    onAsBinder();  };  
        这两个模版在使用的时候,起到得作用实际上都是双继承:使用者定义一个接口INTERFACE,然后使用BnInterface和BpInterface两个模版结合自己的接口,构建自己的BnXXX和BpXXX两个类。
        DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE两个宏用于帮助BpXXX类的实现:
#define DECLARE_META_INTERFACE(INTERFACE)                               /      static const String16 descriptor;                                   /      static sp asInterface(const sp& obj);        /      virtual String16 getInterfaceDescriptor() const;                    /  #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       /      const String16 I##INTERFACE::descriptor(NAME);                      /      String16 I##INTERFACE::getInterfaceDescriptor() const {             /          return I##INTERFACE::descriptor;                                /      }                                                                   /      sp I##INTERFACE::asInterface(const sp& obj)  /      {                                                                   /          sp intr;                                          /          if (obj != NULL) {                                              /              intr = static_cast(                          /                  obj->queryLocalInterface(                               /                          I##INTERFACE::descriptor).get());               /              if (intr == NULL) {                                         /                  intr = new Bp##INTERFACE(obj);                          /              }                                                           /          }                                                               /          return intr;                                                    /      }  
       在定义自己的类的时候,只需要使用DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE两个接口,并结合类的名称,就可以实现BpInterface中asInterface()和getInterfaceDescriptor()两个函数。
       此外,IInterface还起到了转换的作用,IXXXService继承自IInterface,而IInterface中的asBinder()方法,会将自身,也就是IXXXService转换成一个IBinder对象,而asInterface接口则是将IIBinder转换为IXXXService接口。
templateinline sp interface_cast(const sp& obj){return INTERFACE::asInterface(obj);}
      由此可知,使用interface_cast的作用就是将IBinder实例转化成IXXXService实例。              可以看出,C空间的IBinder接口和java空间类似,下图可以看出C空间的binder的Proxy-stub模式







更多相关文章

  1. 2011.09.07(5)——— android 跨进程通信之content provider + Aut
  2. Android跨进程通信传输大数据
  3. SystemServer
  4. Android(安卓)5.0有哪些变化
  5. Fedora 12安装Android(安卓)SDK
  6. 无法安装ADT(无法访问https://dl-ssl.google.com/android/eclipse
  7. Android(安卓)横屏不重启 Activity
  8. Android基础系列-----------Android进程/线程管理应用示例(Androi
  9. android 几种发送短信的方法

随机推荐

  1. Android状态栏通知
  2. android蓝牙开发入门到精通4------通信标
  3. Android Service学习之IntentService 深
  4. Android手机号、串号获取
  5. android获取屏幕的宽高
  6. Android获取手屏幕尺寸
  7. Android Power Management【by Steve Guo
  8. Android中播放视频
  9. Android根据不同语言切换图片
  10. android 命令行创建工程