相关源码路径

/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整体通信架构如下图所示:

 Binder解析_第1张图片

(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层来完成的。

 Binder解析_第2张图片

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


1 binder介绍

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

Binder解析_第3张图片 

(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层所涉及的类如下:

Binder解析_第4张图片

【初始化】

         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层。整个调用关系如下。
Binder解析_第5张图片


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解析_第6张图片

       这就是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模型图:
Binder解析_第7张图片
     上图中绿色部分就是生成的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类图如下: Binder解析_第8张图片

      先看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的实现类,这里就总结一下他们的区别:
Binder解析_第9张图片
(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模式
Binder解析_第10张图片






更多相关文章

  1. 2011.09.07(5)——— android 跨进程通信之content provider + Aut
  2. Android跨进程通信传输大数据
  3. 无法安装ADT(无法访问https://dl-ssl.google.com/android/eclipse
  4. Android基础系列-----------Android进程/线程管理应用示例(Androi
  5. android 几种发送短信的方法
  6. 【Android】一种提高Android应用进程存活率新方法
  7. Android的进程优先级与进程回收详解
  8. 守护进程通信之Socket
  9. 更改Android AVD模拟器创建路径位置的方法

随机推荐

  1. 解决Error inflating class android.supp
  2. Android利用Jpush实现异地登陆下线
  3. Android 类加载机制以及基于类加载机制的
  4. 利用AS(3.0)工具将工程打包成jar
  5. WiFi流程
  6. Android 属性动画(Property Animation) 完
  7. 动画 -- View动画 -- 缩放动画
  8. android 学习笔记3--静默安装功能的实现
  9. Android 集成百度地图实现设备定位
  10. Android系统源码阅读(18):Android 应用的显