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。

java代码:

  1. IBinder b = ServiceManager.getService("activity");
  2. 继续看下getService方法,在getService中对数据进行了序列化封装,并通过BinderProxy的native方法向ServiceManager发送请求,获取Binder的代理对象。看下getService代码:
java代码:
  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(); Parcel reply = Parcel.obtain();
  9. data.writeInterfaceToken(IServiceManager.descriptor);
  10. data.writeString(name);
  11. mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
  12. IBinder binder = reply.readStrongBinder();
  13. reply.recycle();
  14. data.recycle();
  15. return binder;
  16. }

也就是说,在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代码:

  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代码:

  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中的进程和线程
  2. Android面试题(六)--重要
  3. Android(安卓)文件操作心得体会
  4. Android(安卓)3D 游戏开发教程– Part I-VI
  5. Android(安卓)Flutter 混合开发高仿大厂 App
  6. 如何在Android真机上检测是否有Google Map add-on
  7. Android(安卓)内存管理 &Memory Leak & OOM 分析
  8. Mac OS X 编译Android内核源代码
  9. 关于 android 子进程域名解析失败的问题

随机推荐

  1. Android 字体自适应设置
  2. Android ViewGroup中有关测量的方法
  3. TextView 限制最大行数、最小行数、字数
  4. Android 对话框(Dialog)大全
  5. 管理Android通信录
  6. Android Activity的启动过程(API27 源码分
  7. cocos2d-x 1.0.1 for Android 使用Box2D
  8. Android实现TextView部分文本监听单击事
  9. Android面试笔试集锦
  10. 面试准备(待整理、未完待续。。)