Binder机制是android中实现的进程间通信的架构,它采用的是c/s架构,client通过代理完成对server的调用。

    ServiceManager

    既然这里提到了server,那么我们有必要先了解下在android中是怎么来管理server的。先来看一个重要的Native进程:ServiceManager,从名字可以看出来,这个是用来管理所有server的。在init进程启动之后,会启动另外两个重要的进程,一个是我们上一篇讲的Zygote进程,另外一个就是这个ServiceManager进程了,这两个进程启动之后就建立了android的运行环境和server的管理环境。ServiceManager进程启动之后其他server就可以通过ServiceManager的add_service和check_service来添加和获取特定的server了。关于ServiceManager在接下来会详细介绍,因为Binder会涉及到ServiceManager,所以先简单介绍下,有个大概印象,知道他是干什么的就行了。

    Binder与进程间通信

    在本篇介绍中,我们所指的客户端没有特别说明的话就指应用程序。应为service和serviceManager通信也会涉及到IPC。

    我们还是从activity的启动开始来研究Binder的机制。来看下startActivity涉及通信的类图:


    在ActivityManagerProxy中,有这句代码

    [java] view plain copy
    1. IBinderb=ServiceManager.getService("activity");
    2. 继续看下getService方法,在getService中对数据进行了序列化封装,并通过BinderProxy的native方法向ServiceManager发送请求,获取Binder的代理对象。看下getService代码:

    [java] view plain copy
    1. /*
    2. *从ServiceManager中获取service对应的代理Binder
    3. *@paramna
    4. *@return
    5. *@throwsRemoteException
    6. */
    7. publicIBindergetService(Stringname)throwsRemoteException{
    8. Parceldata=Parcel.obtain();
    9. Parcelreply=Parcel.obtain();
    10. data.writeInterfaceToken(IServiceManager.descriptor);
    11. data.writeString(name);
    12. mRemote.transact(GET_SERVICE_TRANSACTION,data,reply,0);
    13. IBinderbinder=reply.readStrongBinder();
    14. reply.recycle();
    15. data.recycle();
    16. returnbinder;
    17. }

    也就是说,在android中进行IPC的话,需要先通过ServiceManager获得客户端的代理,然后再通过该代理与对应的service进行通信。

    1. 建立和ServiceManager的连接,获取客户端对象的代理Binder。
    2. 客户端再通过该代理binder和服务器端进行通信。

    真正的Binder

    我们在上面所提到的这些Binder实际上只是JVM中的Binder,主要作用是提供了访问C++中的代理Binder,叫做BpBinder(BproxyBinder)。真正的Binder是Linux上的一个驱动设备,专门用来做android的数据交换。

    从上面分析可以看出,一次IPC通信大概有以下三个步骤:

  1. 在JVM中对数据进行序列化,并通过BinderProxy传递到C++中。
  2. C++中的BpBinder对数据进行处理,并传入到Binder设备中(这里是在ProcessState类中处理并调用BpBinder).
  3. Service从内核设备中读取数据。

既然在C++中,处理数据主要是在ProcessState中,那么我们就来看看ProcessState的代码,在getContextObject中调用了getStrongProxyForHandle方法,从而获取了代理对象BpBinder:

    [java] view plain copy
    1. sp<IBinder>ProcessState::getStrongProxyForHandle(int32_thandle)
    2. {
    3. sp<IBinder>result;
    4. AutoMutex_l(mLock);
    5. handle_entry*e=lookupHandleLocked(handle);
    6. if(e!=NULL){
    7. //WeneedtocreateanewBpBinderifthereisn'tcurrentlyone,ORwe
    8. //areunabletoacquireaweakreferenceonthiscurrentone.Seecomment
    9. //ingetWeakProxyForHandle()formoreinfoaboutthis.
    10. IBinder*b=e->binder;
    11. if(b==NULL||!e->refs->attemptIncWeak(this)){
    12. b=newBpBinder(handle);
    13. e->binder=b;
    14. if(b)e->refs=b->getWeakRefs();
    15. result=b;
    16. }else{
    17. //Thislittlebitofnastynessistoallowustoaddaprimary
    18. //referencetotheremoteproxywhenthisteamdoesn'thaveone
    19. //butanotherteamissendingthehandletous.
    20. result.force_set(b);
    21. e->refs->decWeak(this);
    22. }
    23. }
    24. returnresult;
    25. }

    再来看看BpBinder中的transact方法代码:

    [java] view plain copy
    1. status_tBpBinder::transact(
    2. uint32_tcode,constParcel&data,Parcel*reply,uint32_tflags)
    3. {
    4. //Onceabinderhasdied,itwillnevercomebacktolife.
    5. if(mAlive){
    6. status_tstatus=IPCThreadState::self()->transact(
    7. mHandle,code,data,reply,flags);
    8. if(status==DEAD_OBJECT)mAlive=0;
    9. returnstatus;
    10. }
    11. returnDEAD_OBJECT;
    12. }
    在BpBinder中的transact函数中,只是调用了IPCThreadState::self()->transact方法,也就是说,数据处理是在IPCThreadState类中的transact。在transact中,它把请求的数据经过Binder设备发送给了Service。Service处理完请求后,又将结果原路返回给客户端。

    总结:

  1. 在android中,使用Binder进行进程间的通信,并采用C/S架构
  2. Android中的Binder分为JVM中的、C++中的、和真正的linux中的Binder块设备
  3. 进程间通信首先是从JVM中对数据进行转化并传递到C++中,C++中的BpBinder对数据进行处理写入到linux中的Binder设备,并接受Service端得请求,请求完毕后按照原路返回给调用端。

更多相关文章

  1. 40个Android面试题
  2. Android(安卓)Loader的使用以及手机通讯录的获取方法
  3. Android通过Servlet连接MySQL 实现登陆/注册(数据库+服务器+客户
  4. 2种方式进行Spinner数据的添加
  5. Intent小结
  6. Android(安卓)Intent Filter 简析
  7. Android(安卓)Service两种启动方式详解(总结版)
  8. Android程序猿挑战高薪必会的十大面试题
  9. Android(安卓)Wear 数据类型和接口的发送和同步数据概述

随机推荐

  1. android studio 报编码 GBK 的不可映射字
  2. Android APK安装失败,共享用户不兼容 INST
  3. android 状态栏透明,源码修改教程
  4. Android控件基本属性介绍
  5. Android:Debug certificate expired on D
  6. android 获取设备型号
  7. android > 调用拨打电话 并子线程监控然
  8. 基于Phone模块的Service实现
  9. Android API 指南
  10. Android使用系统Intent实现分享功能及将