我们知道,在Android里Binder是进程间通信的基础,而且,Android的应用程序天生就支持Binder通信,为什么?没了Binder,Android里的四大组件将没法运转,比如Activity的启动其实是通过AMS来管理的,Activity里的那个token成员变量其实就是Activity在AMS中一条记录的引用,而这些都是跨进程的。
       既然Binder是Android里跨进程交换数据的基础,像查询系统服务这些操作也是通过IServiceManager这个IBinder来完成的,那么问题来了,Android世界里的第一个IBinder是什么?在那里实现的?
       这就是说我们要找到最先孵化出蛋的小鸡在那里,要不这么多小鸡那里来的:)嗯,这就是关键,还记得上节我们说过的ServiceManager进程的初始化吗?对,就是它,上节我们说这个进程实际上就是IServiceManager这个IBinder的具体实现,到这里可能有点晕了,一个进程怎么是接口的实现呢,准确说是ServiceManager进程的svcmgr_handler函数实现了IServiceManager接口功能的,还是晕,这不符合面向对象编程,但事实就是这样,ServiceManager是借助Binder驱动来完成这些功能,而我们获取的IServiceManager接口实际是通过BpBinder(这个后面会讲)来代理的,其handle为0,下面给出ServiceManager进程启动初始化流程图。

(2) Android中Binder调用流程 --- Binder环境的初始化_第1张图片

       根据上图,我们讲下具体的流程,分为两个部分:IServiceManager初始化和使用。
       

IServiceManager初始化

    1)ServiceManager进程启动;
    2)初始化Binder驱动设备;
    3)向Binder驱动申请成为Binder的管理者;
    4)Binder驱动内部生成一个全局的binder_node节点,并设置其handle为0;
    5)ServiceManager进程进入死循环,不断从Binder驱动读取客户端请求;
    6) ServiceManager收到客户端请求,解析请求,根据解析出的命令分别处理;
    7) 把处理结果通过Binder驱动发送给请求的客户端,完成一次命令处理。

客户端使用请求

       我们这里以注册Service为例进行说明。
       1)通过ServiceManagerNative获取IServiceManager代理接口;
       2)获取的IServiceManager接口远程代理对象在JAVA层对应的是BinderProxy,在Native层对应的是BpBinder;
       3)BinderProxy是通过BinderInternal.getContextObject()获取的;
       4)BinderInternal.getContextObject()是一个native方法,其内部就是通过handle为0来生成一个BpBinder对象,然后把这个本地对象保存在BinderProxy的mObject成员变量里(在native层通过这个成员变量得到native层的BpBinder)。
       5)因此最终IBinder实际调用的是BpBinder的transact()函数;
       6)在BpBinder的transact()函数内部,实际调用的是IPCThreadState的transact来处理的,数据经过层层封装,最终调用ioctl(mProcess->mDriverFD,BINDER_WRITE_READ, &bwr)把请求发送到Binder驱动层;
       7)Binder驱动层收到请求后,解析发现handle为0,然后找到handle为0对应的进程ServiceManager,最后把请求放到ServiceManager的处理队列并唤醒ServiceManager;
       8)ServiceManager收到客户端请求后,根据请求码进行处理,这里是注册Service,因此在列表中插入注册的Service信息,这里要注意,新注册的Service就是个IBinder,其对应handle由Binder驱动生成了,因此,这里会根据handle查询列表是否存在,不存在插入一条Service信息。

通过上面流程的描述,有几个关键点

       1)我们实际获取的IServiceManager仅仅是一个代理,其本地对象实现是BpBinder;
       2)IServiceManager的handle固定是0,其没有名称,也不需要;
       3)IServiceManager的具体实现是ServiceManager结合Binder驱动完成的;
       4)每个IBinder对象都和一个32位的整型handle一一对应,并且这个handle是由Binder驱动层生成的。

       到这里大家应该明白了Android世界里的第一个IBinder是谁了,没错,就是ServiceManager,其实现了IServiceManager的接口功能,这也是Android设计的巧妙之处。
       知道了第一个IBinder之后,接下来我们看下应用进程怎么初始化Binder环境并使用的。其实,在ServiceManager里我们已经知道怎么样使用Binder了,就是通过ioctl系统调用完成的,并使用命令BINDER_WRITE_READ完成一次读写操作。
       Binder驱动里定义很多命令,用来控制读写、环境参数设置等。回到主题,看下应用进程怎么初始化Binder环境的。
       我们知道应用程序进程是由Zygote进程fork出来的,而这最终会调用ZygoteInit.zygoteInit这个方法。

       frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

public static final void zygoteInit(int targetSdkVersion, String[] argv,
830            ClassLoader classLoader) throws Zygote.MethodAndArgsCaller {
......
837
838        RuntimeInit.commonInit();
839        ZygoteInit.nativeZygoteInit();
840        RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);
841    }

       我们看到调用了本地方法ZygoteInit.nativeZygoteInit();
       frameworks/base/core/jni/AndroidRuntime.cpp

static void com_android_internal_os_ZygoteInit_nativeZygoteInit(JNIEnv* env,
jobject clazz)
222{
223    gCurRuntime->onZygoteInit();
224}

       gCurRuntime就是一个AppRuntime类型的对象:

       frameworks/base/cmds/app_process/app_main.cpp

virtual void onZygoteInit()
92    {
93        sp proc = ProcessState::self();
94        ALOGV("App process: starting thread pool.\n");
95        proc->startThreadPool();
96    }

       sp proc = ProcessState::self();这句代码初始化了Binder驱动设备并调用mmap分配了1M的缓存;接下来proc->startThreadPool();这句代码则把新建一个线程作为Binder线程(处理Binder的请求等等)。
       所以,一开始应用进程仅仅启动一个Binder线程,而SystemService开始启动两个binder线程来处理请求(SystemServer主线程是一个,通过ProcessState启动一个)。

       本系列文章均为原创,主要总结作者多年在软件行业的一些经验,和大家共同学习、进步,转载请注明出处,谢谢!

更多相关文章

  1. OpenGL,Android注意事项初始化顺序 NullPointer
  2. Android进程与线程基本知识四
  3. FregServer进程,返回BR_REPLY
  4. android-2.2以下杀进程方法:restartPackage();
  5. Android P WMS初始化过程
  6. FregClient和FregServer进程间通信
  7. Android 进程间通信:AIDL
  8. AIDL --- Android中的远程接口(3)
  9. Android 进程间通信(IPC)

随机推荐

  1. Android使用binder访问service的方式
  2. Android(安卓)Camera2 Mediacodec编码
  3. android 调节媒体音量
  4. android ScrollView嵌套RecyclerView只显
  5. Android(安卓)平板电脑的判断方法
  6. Android(安卓)手机端与服务端POST数据交
  7. Android(安卓)RectF类的构造函数参数说明
  8. Android(安卓)Drawable绘图
  9. Android(安卓)SQLite 抽象出CRUD操作工具
  10. Android(安卓)- View的绘制流程一(measure