Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1306001
  • 博文数量: 478
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 4833
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-28 11:12
文章分类

全部博文(478)

文章存档

2019年(1)

2018年(27)

2017年(21)

2016年(171)

2015年(258)

我的朋友

分类: Android平台

2015-10-19 09:33:28

http://blog.csdn.net/xieqibao/article/details/6584049

Android 之 Binder与进程间通信

分类: Android2011-07-04 17:43 8415人阅读 评论(4) 收藏 举报

    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 plaincopy
    1. IBinder b = ServiceManager.getService("activity");  
    2. 继续看下getService方法,在getService中对数据进行了序列化封装,并通过BinderProxy的native方法向ServiceManager发送请求,获取Binder的代理对象。看下getService代码:  


    [java] view plaincopy
    1. /* 
    2.    * 从ServiceManager中获取service对应的代理Binder 
    3.    * @param na 
    4.    * @return 
    5.    * @throws RemoteException 
    6.    */  
    7.   public IBinder getService(String name) throws RemoteException {  
    8.       Parcel data = Parcel.obtain();  
    9.       Parcel reply = Parcel.obtain();  
    10.       data.writeInterfaceToken(IServiceManager.descriptor);  
    11.       data.writeString(name);  
    12.       mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);  
    13.       IBinder binder = reply.readStrongBinder();  
    14.       reply.recycle();  
    15.       data.recycle();  
    16.       return binder;  
    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 plaincopy
    1. sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)  
    2. {  
    3.     sp<IBinder> result;  
    4.     AutoMutex _l(mLock);  
    5.     handle_entry* e = lookupHandleLocked(handle);  
    6.     if (e != NULL) {  
    7.         // We need to create a new BpBinder if there isn't currently one, OR we  
    8.         // are unable to acquire a weak reference on this current one.  See comment  
    9.         // in getWeakProxyForHandle() for more info about this.  
    10.         IBinder* b = e->binder;  
    11.         if (b == NULL || !e->refs->attemptIncWeak(this)) {  
    12.             b = new BpBinder(handle);  
    13.             e->binder = b;  
    14.             if (b) e->refs = b->getWeakRefs();  
    15.             result = b;  
    16.         } else {  
    17.             // This little bit of nastyness is to allow us to add a primary  
    18.             // reference to the remote proxy when this team doesn't have one  
    19.             // but another team is sending the handle to us.  
    20.             result.force_set(b);  
    21.             e->refs->decWeak(this);  
    22.         }  
    23.     }  
    24.     return result;  
    25. }  


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


    [java] view plaincopy
    1. status_t BpBinder::transact(  
    2.     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)  
    3. {  
    4.     // Once a binder has died, it will never come back to life.  
    5.     if (mAlive) {  
    6.         status_t status = IPCThreadState::self()->transact(  
    7.             mHandle, code, data, reply, flags);  
    8.         if (status == DEAD_OBJECT) mAlive = 0;  
    9.         return status;  
    10.     }  
    11.     return DEAD_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端得请求,请求完毕后按照原路返回给调用端。
阅读(378) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~