该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列。该系列引用了《Android开发艺术探索》以及《深入理解Android 卷Ⅰ,Ⅱ,Ⅲ》中的相关知识,另外也借鉴了其他的优质博客,在此向各位大神表示感谢,膜拜!!!另外,本系列文章知识可能需要有一定Android开发基础和项目经验的同学才能更好理解,也就是说该系列文章面向的是Android中高级开发工程师。


我们在上一篇中比较详尽的介绍了Android的消息机制,不过有一些内容我们在不理解Android Binder的话是无法讲解清楚的。对于初学Android的朋友而言,最难却又最想掌握的恐怕就是Binder机制了,因为Android系统基本上可以看作是一个基于Binder通信的C/S架构。 Binder就像网络一样,把系统的各个部分连接在了一起,因此它是非常重要的。我们下面会Android Binder机制进行从上到下从易到难的分层次讲解,从而既能让初学者对Binder有一定认识,也能让有一定Android基础的人获得收获。
注:下文中的源码均出自android-6.0.0_r5

对于初学者来说,深入Android Binder机制是非常不明智的。Android Binder机制大都涉及Java层、Native层、驱动层这三三个方面,对于初学者来说想啃这三块硬骨头很容易磕着牙。我们这这一节概述从以下几个方面让你从比较宏观的角度理解Android Binder。

在该系列博客中的第一章我们就说起了Android进程相关问题,Android故意弱化了进程的概念,而用相对容易理解的四大组件。可是我们在稍微深入Android的时候,那么进程是绕不过的。默认情况下,同一个应用程序中的所有组件运行在同一个进程中,而且绝大多数的应用程序也都是这样的。这个默认进程是用这个应用的包名来命名的。

我们在运行App的时候经常需要使用一些系统服务,比如剪切板服务,而剪切板服务是运行在SystemServer进程中的。那我们的App是怎么使用剪切板服务的呢,我们都知道进程是相互独立的,静态变量等等都无法共用。这就涉及到进程间的通信了,即IPC。我们都知道Android是基于Linux内核的,那我们简单介绍下Linux下的几种IPC机制。

管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。

  • 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道
  • 只能用于父子进程或者兄弟进程之间(具有亲缘关系的进程)。比如fork或exec创建的新进程,在使用exec创建新进程时,需要将管道的文件描述符作为参数传递给exec创建的新进程。当父进程与使用fork创建的子进程直接通信时,发送数据的进程关闭读端,接受数据的进程关闭写端。
  • 管道只能在本地计算机中使用,而不可用于网络间的通信。

命名管道是一种特殊类型的文件,它在系统中以文件形式存在。这样克服了管道的弊端,他可以允许没有亲缘关系的进程间通信。

共享内存是在多个进程之间共享内存区域的一种进程间的通信方式,由IPC为进程创建的一个特殊地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到自己的地址空间中。所有进程都可以访问共享内存中的地址,如果一个进程向共享内存中写入了数据,所做的改动将立刻被其他进程看到。

  • 共享内存是IPC最快捷的方式,共享内存方式直接将某段内存段进行映射,多个进程间的共享内存是同一块的物理空间,仅仅映射到各进程的地址不同而已,因此不需要进行复制,可以直接使用此段空间。
  • 共享内存本身并没有同步机制,需要程序员自己控制。

    内存映射是由一个文件到一块内存的映射,在此之后进程操作文件,就像操作进程空间里的内存地址一样了。

    套接字机制不但可以单机的不同进程通信,而且使得跨网机器间进程可以通信。
    套接字的创建和使用与管道是有区别的,套接字明确地将客户端与服务器区分开来,可以实现多个客户端连到同一服务器。

作为Android系统下的一种IPC机制,其本质上与上面罗列出的IPC机制并无本质上的不同,都是作为进程间通信的一种手段。并且在Android系统中也不是只存在Binder这一种进程间通信的方式,在有些地方也使用了Socket。既然Linux已经提供了众多IPC机制,那么Android 为何还要使用Binder作为主要的进程间通信的方式呢,那么当然有他的优点存在。

  • 采用C/S的通信模式。而在linux通信机制中,目前只有socket支持C/S的通信模式,但socket有其劣势,具体参看第二条。
  • 有更好的传输性能。对比于Linux的通信机制,socket:是一个通用接口,导致其传输效率低,开销大;管道和消息队列:因为采用存储转发方式,所以至少需要拷贝2次数据,效率低;共享内存:虽然在传输时没有拷贝数据,但其控制机制复杂(比如跨进程通信时,需获取对方进程的pid,得多种机制协同操作)。
  • 安全性更高。Linux的IPC机制在本身的实现中,并没有安全措施,得依赖上层协议来进行安全控制。而Binder机制的UID/PID是由Binder机制本身在内核空间添加身份标识,安全性高;并且Binder可以建立私有通道,这是linux的通信机制所无法实现的(Linux访问的接入点是开放的)。
  • 对用户来说,通过binder屏蔽了client的调用server的隔阂,client端函数的名字、参数和返回值和server的方法一模一样,对用户来说犹如就在本地(也可以做得不一样),这样的体验或许其他ipc方式也可以实现,但binder出生那天就是为此而生。

Java层Binder的功能,依赖于Native层Binder来实现,可以认为Java层Binder架构是Native层Binder架构的一个镜像。但是这并不影响我们分析Android Java层Binder的功能。我们用一个例子来说明这个过程。

我们在第一篇中就讲解了SystemServer这个进程,这个进程和zygote进程一起撑起了Android 世界,他们之中有一个崩溃,Android世界就会砰然倒塌。Android许多的重要的系统服务如AMS、PMS等都运行在SystemServer进程中。但是还有一个比较重要的进程ServiceManager进程(简称SM)跟zygote是兄弟进程。这个进程的作用是用来统一管理服务,如AMS。它们之间的关系如下。

我们的AMS需要向SM进程中注册信息,其他进程如果想使用AMS,那么先和ServiceManager进程进行通信查询,接着再和AMS所在SystemServer进程通信。这部分关系图如下

我们这里仅上图分析①②③中的一条道路,我们来分析③,即我们的应用进程(Client)如何与服务进程(Server)交互。

Java层的Binder,我们来看涉及的类的结构图

[IBinder.java]

  1. public interface IBinder {
  2. //交互函数
  3. public boolean transact(int code, Parcel data, Parcel reply, int flags)
  4. throws RemoteException;
  5. }

我们接着来看Binder和BinderProxy 他们都声明在Binder.java中

[Binder.java]

  1. /**
  2. Binder类
  3. */
  4. public class Binder implements IBinder {
  5. public final boolean transact(int code, Parcel data, Parcel reply,
  6. int flags) throws RemoteException {
  7. ......
  8. //这里调用了onTransact函数进行处理,一般情况下这个函数都会被它的子类重写
  9. boolean r = onTransact(code, data, reply, flags);
  10. if (reply != null) {
  11. reply.setDataPosition(0);
  12. }
  13. return r;
  14. }
  15. }
  16. /**
  17. BinderProxy类
  18. */
  19. final class BinderProxy implements IBinder {
  20. public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
  21. //直接以JNI的方式调用Native层的transact函数
  22. return transactNative(code, data, reply, flags);
  23. }
  24. public native boolean transactNative(int code, Parcel data, Parcel reply,
  25. int flags) throws RemoteException;
  26. }

通用的IPC流程如下

现在假设下面一个场景,我们的应用进程即我们的App想要使用ActivityManagerService的startActivity函数(这种场景肯定有的,当我们拿到手机的时候,手机已经预装了许多App,其中Launcher App(桌面管理App)是在Android系统启动完成之后启动的第一个App,我们安装好一个应用后,点击应用图标即发出Intent,想要启动另一个App中的Activity,我们在AndroidManifest.xml中注册了Main Activity)。Launcher App所在的进程要与AMS所在的进程SystemServer进程交互。
我们来看这个例子。按照上面的通用流程我们猜测Launcher进程与SystemServer进程交互过程也如上图所示,那么按照这个思路我们来看。分为3点:

这一部分是我们的上图中的test函数所声明的类或者接口,我们的Client端代理和Server端服务都要实现这个函数。果然有
[IActivityManager.java]

  1. public interface IActivityManager extends IInterface {
  2. public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
  3. String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flags,
  4. ProfilerInfo profilerInfo, Bundle options) throws RemoteException;
  5. ......
  6. }

这里声明了我们将要调用的业务函数startActivity,那么接着第二点

ActivityManagerProxy是在ActivityManagerNative.java中声明的内部类

  1. class ActivityManagerProxy implements IActivityManager
  2. {
  3. public ActivityManagerProxy(IBinder remote)
  4. {
  5. mRemote = remote;
  6. }
  7. public IBinder asBinder()
  8. {
  9. return mRemote;
  10. }
  11. public int startActivity(IApplicationThread caller, String callingPackage, Intent intent,
  12. String resolvedType, IBinder resultTo, String resultWho, int requestCode,
  13. int startFlags, ProfilerInfo profilerInfo, Bundle options) throws RemoteException {
  14. Parcel data = Parcel.obtain();
  15. Parcel reply = Parcel.obtain();
  16. data.writeInterfaceToken(IActivityManager.descriptor);
  17. data.writeStrongBinder(caller != null ? caller.asBinder() : null);
  18. data.writeString(callingPackage);
  19. intent.writeToParcel(data, 0);
  20. data.writeString(resolvedType);
  21. data.writeStrongBinder(resultTo);
  22. data.writeString(resultWho);
  23. data.writeInt(requestCode);
  24. data.writeInt(startFlags);
  25. if (profilerInfo != null) {
  26. data.writeInt(1);
  27. profilerInfo.writeToParcel(data, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
  28. } else {
  29. data.writeInt(0);
  30. }
  31. if (options != null) {
  32. data.writeInt(1);
  33. options.writeToParcel(data, 0);
  34. } else {
  35. data.writeInt(0);
  36. }
  37. //看这里果然是通过mRemote.transact函数,这里的mRemote是BinderProxy类,关于这一点我们在Native层分析的时候再给出
  38. mRemote.transact(START_ACTIVITY_TRANSACTION, data, reply, 0);
  39. reply.readException();
  40. int result = reply.readInt();
  41. reply.recycle();
  42. data.recycle();
  43. return result;
  44. }
  45. ......
  46. }

ActivityManagerNative是继承于Binder的抽象类,并重写了onTransact方法

  1. public abstract class ActivityManagerNative extends Binder implements IActivityManager{
  2. @Override
  3. public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
  4. throws RemoteException {
  5. //根据code处理相应的业务逻辑,我们这里是START_ACTIVITY_TRANSACTION
  6. switch (code) {
  7. case START_ACTIVITY_TRANSACTION:
  8. {
  9. data.enforceInterface(IActivityManager.descriptor);
  10. IBinder b = data.readStrongBinder();
  11. IApplicationThread app = ApplicationThreadNative.asInterface(b);
  12. String callingPackage = data.readString();
  13. Intent intent = Intent.CREATOR.createFromParcel(data);
  14. String resolvedType = data.readString();
  15. IBinder resultTo = data.readStrongBinder();
  16. String resultWho = data.readString();
  17. int requestCode = data.readInt();
  18. int startFlags = data.readInt();
  19. ProfilerInfo profilerInfo = data.readInt() != 0
  20. ? ProfilerInfo.CREATOR.createFromParcel(data) : null;
  21. Bundle options = data.readInt() != 0
  22. ? Bundle.CREATOR.createFromParcel(data) : null;
  23. int result = startActivity(app, callingPackage, intent, resolvedType,
  24. resultTo, resultWho, requestCode, startFlags, profilerInfo, options);
  25. reply.writeNoException();
  26. reply.writeInt(result);
  27. return true;
  28. }
  29. }
  30. }

既然ActivityManagerNative是个抽象类,那么谁真正实现了呢


[ActivityManagerService.java]

  1. public final class ActivityManagerService extends ActivityManagerNative
  2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  3. //重写了onTransact函数
  4. @Override
  5. public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
  6. throws RemoteException {
  7. ......
  8. try {
  9. //调用父类即ActivityManagerNative的onTransact函数
  10. return super.onTransact(code, data, reply, flags);
  11. } catch (RuntimeException e) {
  12. throw e;
  13. }
  14. }
  15. }

Launcher进程与SystemServer进程交互过程如下

关于Java层的Binder机制,我们只需要理解以BinderProxy代表的代理端和Binder代表的服务端的概念即可,例如我们本例中的AMS,AMS是运行在SystemServer进程中的服务端,它间接继承于Binder,在得到相关请求后,会调用AMS重写的onTransact函数进行逻辑处理。那么这个请求就是是AMS的客户端ActivityManagerProxy通过Binder的方式发给它的,ActivityManagerProxy发送这个请求的方式,是通过调用其内部的成员变量mRemote,这个mRemote其实是BinderProxy的对象,然后BinderProxy通过JNI调用Native层对应函数,最终通过Binder驱动达到与SystemServer交互的目的。

那么还遗留下以下几个问题:

1. 服务器端的代理怎么获得的

2. 位于代理类中的mRemote这个变量

要想理解好上面的个问题,我们必须向Native层进军。

我们依然以AMS分析,我们先来想一下我们在用户进程中即我们的App中想使用AMS或者其他剪切板之类的系统服务函数了怎么办??按照上面的分析我们要获得AMS的代理ActivityManagerProxy

[ActivityManagerNative.java]

  1. //这里我们的App进程从SM进程得到AMS服务对应的客户端代理BinderProxy
  2. IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
  3. //以BinderProxy为参数得到我们ActivityManagerProxy,并把BinderProxy对象存储在mRemote变量中
  4. IActivityManager am = asInterface(b);
  5. return am;

到这里我们就有以下问题,本小节分析1,2

1. 既然可以通过SM获得对应的客户端代理,那么AMS必定已经注册在SM中了,那么怎么注册的呢?

2. AMS代理是如何获得的?

3. AMS代理是如何与Binder通信的?

我们来一一分析,在分析问题之前我们先做一个假设,这个假设至关重要,那就是不管我们的SystemServer进程与SM进程交互也好还是我们的App进程与SM进程也好,SM的代理已经事先创建完毕,即不管我们在SystemServer端还是App端,在与SM进程交互的时候不用考虑代理怎么获得的。为什么会有如此假设,因为我自己深受其害,由于上述三个过程均是通过Binder,很容易陷入思维混乱。

我们SystemServer进程中的AMS通过”Socket”与SM进程交互,并把自己注册在SM中
SystemServer创建出ActivityManagerService后,最终将调用其setSystemProcess方法:

[SystemServer.java]

  1. public void setSystemProcess() {
  2. try {
  3. //注册服务,第二个参数为this,这里通过“socket”与SM交互
  4. ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
  5. ..........
  6. } catch (PackageManager.NameNotFoundException e) {
  7. ........
  8. }
  9. }

上面的请求最终是通过SM服务代理发送的()

[ServiceManagerNative.java]

  1. public void addService(String name, IBinder service, boolean allowIsolated)
  2. throws RemoteException {
  3. //将数据打包写入Parcel对象
  4. Parcel data = Parcel.obtain();
  5. Parcel reply = Parcel.obtain();
  6. data.writeInterfaceToken(IServiceManager.descriptor);
  7. data.writeString(name);
  8. //注意这个地方,后文分析,此时的service为ActivityManagerService
  9. data.writeStrongBinder(service);
  10. data.writeInt(allowIsolated ? 1 : 0);
  11. //调用BindProxy的transact函数
  12. mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
  13. reply.recycle();
  14. data.recycle();
  15. }

上面的过程已经分析过了, 这里我们主要看一下哪个对应的native层的transact函数

[android_ util_Binder.cpp]

  1. static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
  2. jint code, jobject dataObj, jobject replyObj, jint flags)
  3. {
  4. ........
  5. //将java对象转化为native对象
  6. Parcel* data = parcelForJavaObject(env, dataObj);
  7. .........
  8. Parcel* reply = parcelForJavaObject(env, replyObj);
  9. ........
  10. //得到native层的BpBinder
  11. IBinder* target = (IBinder*)
  12. env->GetLongField(obj, gBinderProxyOffsets.mObject);
  13. ........
  14. //通过BpBinder利用IPCThreadState,将请求通过Binder驱动发送给SM进程
  15. status_t err = target->transact(code, *data, reply, flags);
  16. ........
  17. }

SM进程收到信息后便处理这个消息(这个说法并不准确,准确的说法是,SM进程中主线程一直在与binder设备交互,想必读者也猜到了for(;;)),有消息时便通过预先定义好的函数进行处理

[service_manager.c]

  1. switch(txn->code) {
  2. case SVC_MGR_ADD_SERVICE:
  3. s = bio_get_string16(msg, &len);
  4. if (s == NULL) {
  5. return -1;
  6. }
  7. handle = bio_get_ref(msg);
  8. allow_isolated = bio_get_uint32(msg) ? 1 : 0;
  9. //do_add_service
  10. if (do_add_service(bs, s, len, handle, txn->sender_euid,
  11. allow_isolated, txn->sender_pid))
  12. return -1;
  13. break;
  14. }
  15. int do_add_service(struct binder_state *bs,
  16. const uint16_t *s, size_t len,
  17. uint32_t handle, uid_t uid, int allow_isolated,
  18. pid_t spid)
  19. {
  20. //结构体si,用来存储服务信息
  21. struct svcinfo *si;
  22. //判断服务有没有权限注册,并不是所有的服务都能注册
  23. if (!svc_can_register(s, len, spid)) {
  24. return -1;
  25. }
  26. //查询服务有没有注册过
  27. si = find_svc(s, len);
  28. if (si) {//已经注册过
  29. if (si->handle) {
  30. ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
  31. str8(s, len), handle, uid);
  32. svcinfo_death(bs, si);
  33. }
  34. si->handle = handle;
  35. } else {//还没有注册过,我们进入这个分支
  36. si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
  37. if (!si) {
  38. ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
  39. str8(s, len), handle, uid);
  40. return -1;
  41. }
  42. //保存一些handle等信息
  43. si->handle = handle;
  44. si->len = len;
  45. memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
  46. si->name[len] = '\0';
  47. si->death.func = (void*) svcinfo_death;
  48. si->death.ptr = si;
  49. si->allow_isolated = allow_isolated;
  50. si->next = svclist;
  51. svclist = si;
  52. }
  53. binder_acquire(bs, handle);
  54. binder_link_to_death(bs, handle, &si->death);
  55. return 0;
  56. }

看到这里SM貌似只保留了一些AMS的信息而已,实际上并不只是如此,我们来看一下上面的保留问题

[Parcel.java]

  1. data.writeStrongBinder(service);
  2. public final void writeStrongBinder(IBinder val) {
  3. //调用了native函数
  4. nativeWriteStrongBinder(mNativePtr, val);
  5. }

跟进[android_os_Parcel.cpp]

  1. static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
  2. {
  3. Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
  4. if (parcel != NULL) {
  5. //native层的parcel
  6. const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
  7. if (err != NO_ERROR) {
  8. signalExceptionForError(env, clazz, err);
  9. }
  10. }
  11. }
  12. sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
  13. {
  14. if (obj == NULL) return NULL;
  15. //obj为Binder类
  16. if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
  17. JavaBBinderHolder* jbh = (JavaBBinderHolder*)
  18. env->GetLongField(obj, gBinderOffsets.mObject);
  19. //调用了JavaBBinderHolder的get方法
  20. return jbh != NULL ? jbh->get(env, obj) : NULL;
  21. }
  22. //obj为BinderProxy类
  23. if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
  24. return (IBinder*)
  25. env->GetLongField(obj, gBinderProxyOffsets.mObject);
  26. }
  27. ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
  28. return NULL;
  29. }

跟进[Pacel.cpp]

  1. status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
  2. {
  3. return flatten_binder(ProcessState::self(), val, this);
  4. }
  5. status_t flatten_binder(const sp<ProcessState>& /*proc*/,
  6. const sp<IBinder>& binder, Parcel* out)
  7. {
  8. flat_binder_object obj;
  9. obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
  10. if (binder != NULL) {//binder不为空
  11. IBinder *local = binder->localBinder();//是不是本地binder,本地的意思是同一个进程中的调用
  12. if (!local) {
  13. BpBinder *proxy = binder->remoteBinder();
  14. if (proxy == NULL) {
  15. ALOGE("null proxy");
  16. }
  17. const int32_t handle = proxy ? proxy->handle() : 0;
  18. obj.type = BINDER_TYPE_HANDLE;
  19. obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
  20. obj.handle = handle;
  21. obj.cookie = 0;
  22. } else {//我们这里明显不是
  23. obj.type = BINDER_TYPE_BINDER;
  24. obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
  25. obj.cookie = reinterpret_cast<uintptr_t>(local);
  26. }
  27. } else {//错误信息
  28. obj.type = BINDER_TYPE_BINDER;
  29. obj.binder = 0;
  30. obj.cookie = 0;
  31. }
  32. return finish_flatten_binder(binder, obj, out);
  33. }

通过上面的代码,我们可以看到当一个服务进行注册时,会将Java层的Binder对象和Native层的BBinder关联起来,于是服务端绑定到了Native层的Binder架构。
此外,addService中打包传入的其实不是ActivityManagerService本身,而是对应的JavaBBinder对象。
这里对应的结构如下图所示:

我们上面SystemServer中的AMS已经在SM中准备好了,那我们ServiceManager.getService(Context.ACTIVITY_SERVICE);
一样的过程,我们知道最终会在service_manager.c中处理

  1. switch(txn->code) {
  2. //这里有个case穿透,,好吧
  3. case SVC_MGR_GET_SERVICE:
  4. case SVC_MGR_CHECK_SERVICE:
  5. s = bio_get_string16(msg, &len);
  6. if (s == NULL) {
  7. return -1;
  8. }
  9. //查询AMS保存在SM中对应的的那个handle
  10. handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
  11. if (!handle)
  12. break;
  13. bio_put_ref(reply, handle);
  14. return 0;
  15. }
  16. 把写入数据后的reply返回
  17. bio_put_uint32(reply, 0);

回到我们的调用处
[ServiceManagerNative.java]

  1. public IBinder getService(String name) throws RemoteException {
  2. Parcel data = Parcel.obtain();
  3. Parcel reply = Parcel.obtain();
  4. data.writeInterfaceToken(IServiceManager.descriptor);
  5. data.writeString(name);
  6. mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
  7. //看这里readStrongBinder,是不是感觉跟我们上面的writeStrongBinder感觉是一对的
  8. IBinder binder = reply.readStrongBinder();
  9. reply.recycle();
  10. data.recycle();
  11. return binder;
  12. }

Parcel的readStrongBinder还是个JNI调用

[android_ os_Parcel.cpp]

  1. static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
  2. {
  3. Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
  4. if (parcel != NULL) {
  5. //这里我们看到了什么,,看函数名字应该是为Binder生成一个java对象吧
  6. return javaObjectForIBinder(env, parcel->readStrongBinder());
  7. }
  8. return NULL;
  9. }

我们先看Pacel的readStrongBinder方法
[Parcel.cpp]

  1. sp<IBinder> Parcel::readStrongBinder() const
  2. {
  3. sp<IBinder> val;
  4. //看到这里,还记得writeStrongBinder中的flatten_binder,这里是unflatten_binder
  5. unflatten_binder(ProcessState::self(), *this, &val);
  6. return val;
  7. }
  8. status_t unflatten_binder(const sp<ProcessState>& proc,
  9. const Parcel& in, sp<IBinder>* out)
  10. {
  11. const flat_binder_object* flat = in.readObject(false);
  12. if (flat) {
  13. switch (flat->type) {
  14. case BINDER_TYPE_BINDER:
  15. *out = reinterpret_cast<IBinder*>(flat->cookie);
  16. return finish_unflatten_binder(NULL, *flat, in);
  17. case BINDER_TYPE_HANDLE:
  18. //到这里我们也清楚了进入这个分支
  19. //调用ProcessState的getStrongProxyForHandle函数
  20. *out = proc->getStrongProxyForHandle(flat->handle);
  21. return finish_unflatten_binder(
  22. static_cast<BpBinder*>(out->get()), *flat, in);
  23. }
  24. }
  25. return BAD_TYPE;
  26. }

继续跟进[ProcessState.cpp]

  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. IBinder* b = e->binder;
  8. if (b == NULL || !e->refs->attemptIncWeak(this)) {
  9. if (handle == 0) {//这里handle为0的情况是为SM准备的,
  10. Parcel data;
  11. status_t status = IPCThreadState::self()->transact(
  12. 0, IBinder::PING_TRANSACTION, data, NULL, 0);
  13. if (status == DEAD_OBJECT)
  14. return NULL;
  15. }
  16. //我们的不为0,在这里创建了BpBinder
  17. b = new BpBinder(handle);
  18. e->binder = b;
  19. if (b) e->refs = b->getWeakRefs();
  20. result = b;
  21. } else {
  22. result.force_set(b);
  23. e->refs->decWeak(this);
  24. }
  25. }
  26. return result;
  27. }

好了剩下最后一个了javaObjectForIBinder

[android_ util_Binder.cpp]

  1. jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) {
  2. if (val == NULL) return NULL;
  3. //如果val是Binder对象,进入下面分支,此时val是BpBinder
  4. if (val->checkSubclass(&gBinderOffsets)) {
  5. // One of our own!
  6. jobject object = static_cast<JavaBBinder*>(val.get())->object();
  7. LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
  8. return object;
  9. }
  10. .........
  11. //调用BpBinder的findObject函数
  12. //在Native层的BpBinder中有一个ObjectManager,它用来管理在Native BpBinder上创建的Java BinderProxy对象
  13. //findObject用于判断gBinderProxyOffsets中,是否存储了已经被ObjectManager管理的Java BinderProxy对象
  14. jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
  15. if (object != NULL) {
  16. jobject res = jniGetReferent(env, object);
  17. ............
  18. //如果该Java BinderProxy已经被管理,则删除这个旧的BinderProxy
  19. android_atomic_dec(&gNumProxyRefs);
  20. val->detachObject(&gBinderProxyOffsets);
  21. env->DeleteGlobalRef(object);
  22. }
  23. //创建一个新的BinderProxy对象
  24. object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
  25. if (object != NULL) {
  26. // The proxy holds a reference to the native object.
  27. env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
  28. val->incStrong((void*)javaObjectForIBinder);
  29. // The native object needs to hold a weak reference back to the
  30. // proxy, so we can retrieve the same proxy if it is still active.
  31. jobject refObject = env->NewGlobalRef(
  32. env->GetObjectField(object, gBinderProxyOffsets.mSelf));
  33. //新创建的BinderProxy对象注册到BpBinder的ObjectManager中,同时注册一个回收函数proxy_cleanup
  34. //当BinderProxy对象detach时,proxy_cleanup函数将被调用,以释放一些资源
  35. val->attachObject(&gBinderProxyOffsets, refObject,
  36. jnienv_to_javavm(env), proxy_cleanup);
  37. // Also remember the death recipients registered on this proxy
  38. sp<DeathRecipientList> drl = new DeathRecipientList;
  39. drl->incStrong((void*)javaObjectForIBinder);
  40. //将死亡通知list和BinderProxy联系起来
  41. env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
  42. // Note that a new object reference has been created.
  43. android_atomic_inc(&gNumProxyRefs);
  44. //垃圾回收相关;利用gNumRefsCreated记录创建出的BinderProxy数量
  45. //当创建出的BinderProxy数量大于200时,该函数将利用BinderInternal的ForceGc函数进行一个垃圾回收
  46. incRefsCreated(env);
  47. return object;
  48. }
  49. }

到这里总算都打通了总体流程如下

还剩下遗留下的两个问题

通过Java层的服务端代理最终调用到BpBinder.transact函数

[BpBinder.cpp]

  1. status_t BpBindertransact(uint32_t code,const Parcel&data,Parcel*replyuint32_t flags){
  2. if(mAlive){
  3. //BpBinder把transact工作交给了IPCThreadState。
  4. status_t status=IPCThreadStateself()->transact(
  5. mHandle,code,data,reply,flags);//mHandle也是参数
  6. if(status==DEAD_OBJECT)mAlive=0
  7. return status
  8. }
  9. return DEAD_OBJECT
  10. }

[IPCThreadState.cpp]

  1. IPCThreadState::IPCThreadState()
  2. : mProcess(ProcessState::self()),
  3. mMyThreadId(gettid()),
  4. mStrictModePolicy(0),
  5. mLastTransactionBinderFlags(0)
  6. {
  7. pthread_setspecific(gTLS, this);
  8. clearCaller();
  9. //mIn和mOut是两个Parcel。 把它看成是发送和接收命令的缓冲区即可。
  10. mIn.setDataCapacity(256);
  11. mOut.setDataCapacity(256);
  12. }
  13. status_t IPCThreadState::transact(int32_t handle,
  14. uint32_t code, const Parcel& data,
  15. Parcel* reply, uint32_t flags)
  16. {
  17. ......
  18. /*
  19. 注意这里的第一个参数BC_TRANSACTION,它是应用程序向binder设备发送消息的消
  20. 息码,而binder设备向应用程序回复消息的消息码以BR_开头。 消息码的定义在
  21. binder_module.h中,请求消息码和回应消息码的对应关系,需要查看Binder驱动的实
  22. 现才能将其理清楚,我们这里暂时用不上。
  23. */
  24. err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
  25. ......
  26. err = waitForResponse(NULL, NULL);
  27. ......
  28. return err;
  29. }
  30. status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
  31. int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
  32. {
  33. //binder_transaction_data是和binder设备通信的数据结构。
  34. binder_transaction_data tr
  35. //果然,handle的值传递给了target,用来标识目的端,其中0是ServiceManager的标志。
  36. tr.target.handle=handle
  37. //code是消息码,是用来switch/case的!
  38. tr.code = code;
  39. tr.flags = binderFlags;
  40. tr.cookie = 0;
  41. tr.sender_pid = 0;
  42. tr.sender_euid = 0;
  43. const status_t err = data.errorCheck();
  44. if (err == NO_ERROR) {
  45. tr.data_size = data.ipcDataSize();
  46. tr.data.ptr.buffer = data.ipcData();
  47. tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
  48. tr.data.ptr.offsets = data.ipcObjects();
  49. } else if (statusBuffer) {
  50. tr.flags |= TF_STATUS_CODE;
  51. *statusBuffer = err;
  52. tr.data_size = sizeof(status_t);
  53. tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
  54. tr.offsets_size = 0;
  55. tr.data.ptr.offsets = 0;
  56. } else {
  57. return (mLastError = err);
  58. }
  59. //把命令写到mOut中,而不是直接发出去,可见这个函数有点名不副实。
  60. mOut.writeInt32(cmd);
  61. mOut.write(&tr, sizeof(tr));
  62. return NO_ERROR;
  63. }
  64. status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
  65. {
  66. uint32_t cmd;
  67. int32_t err;
  68. while (1) {
  69. if ((err=talkWithDriver()) <NO_ERROR) break;
  70. err = mIn.errorCheck();
  71. if (err < NO_ERROR) break;
  72. if (mIn.dataAvail() == 0) continue;
  73. //看见没?这里开始操作mIn了,看来talkWithDriver中
  74. //把mOut发出去,然后从driver中读到数据放到mIn中了。
  75. cmd = mIn.readInt32();
  76. }
  77. }
  78. status_t IPCThreadState::talkWithDriver(bool doReceive)
  79. {
  80. binder_write_read bwr;
  81. //中间东西太复杂了,不就是把mOut数据和mIn接收数据的处理后赋值给bwr吗?
  82. status_t err;
  83. do {
  84. //用ioctl来读写
  85. if (ioctl(mProcess->mDriverFD,BINDER_WRITE_READ, &bwr) >= 0)
  86. err = NO_ERROR;
  87. else
  88. err = -errno;
  89. } while (err == -EINTR);
  90. //到这里,回复数据就在bwr中了,bmr接收回复数据的buffer就是mIn提供的
  91. if (bwr.read_consumed > 0) {
  92. mIn.setDataSize(bwr.read_consumed);
  93. mIn.setDataPosition(0);
  94. }
  95. returnNO_ERROR;
  96. }

我们本篇详细分析了Binder机制,从概述->Java层Binder->Native层Binder->Binder驱动,位于各层次的读者都能获得收获。


不好意思各位,下周有个比较重要的面试,所以暂时不会更新该系列的博客,但是也会更新其他博客。记录准备面试的过程中需要用到的比较容易错误的知识。


此致,敬礼

版权声明:本文为wangle12138原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:http://www.cnblogs.com/wangle12138/p/8087709.html