根据AIDL了解整体调用流程【重点分析AIDL流程】:

在上一次https://www.cnblogs.com/webor2006/p/11741743.html中我们已经对Android Binder机制有了一个比较深刻的认识了,最后也手动通过写了一个AIDL来实现两进程的通讯例子,这次则会更加进一步来以这个实际例子为角度进行流程分析,争取彻底将Android的Binder机制给梳理清。

对于咱们编写的AIDL跨进程的例子而言,用图来简单描述下跨进程:

对于两进程我们是用AIDL文件来进行跨进程通讯的,那这个AIDL用一个形象的例子来解释它其实可以这样来解理:假设进程A是中国人,进程B是日本人:

那两国进行通信是不是得用英语来交流,假如都只会本国语言的话,所以AIDL其实就相当于这个英语,也就是两国交流的一个工具:

而在我们编写了AIDL之后生成的代码中会看到有两个重要的东东:

此时咱们来说明一下这俩东东的含义:

每个进程都会有一个Stub和Proxy,然后我们知道跨进程访问是存在一个C/S架构的,那咱们就把进程A当C端,进程B当S端:

很显然两个进程中间隔了个墙无法直接通讯,要想通讯肯定需要有一个共享内存,如下:

其中Stub是跟服务端交互的,而Proxy是跟客户端交互的:

而当进程B启动时则会主动向共享内存那块注册一个Binder引用,里面会包含进程B的一些信息,如下:

而两进程间的通讯大致流程大概是这样,Proxy是往IBiner写数据,而Stub是从IBinder来读数据的,所以如果进程A要发消息给进程B就会是这样:

而如果服务端往客户端发消息,则类似:

好!!上面是简单对一些概念进行了一个简单图解,是不是这样在之后的分析中会得要确认滴,接下来直接来看AIDL生成的代码,先来看Stub,我们知道它是跟服务端进行通讯的:

这里有一个DESCRIPTOR的常量,它是干嘛用的呢?之后再来看,这里看一个它的构造方法调用了一个attachInterface(),将自身传进去了,先瞅一下它的实现细节:

那这记下来有啥用呢,其实注解上已经有说明了:

有点懵逼,继续来分析,我们知道在C端来绑定服务时会有这么一段代码,如下:

也就是会调到:

咱们来看一下这个方法的实现细节,其中为啥在Stub()构造中要调attachInterface就迎刃而解了,瞅瞅:

那咱们跟到queryLocalInterface方法中去瞅瞅细节:

它是接口,具体实现就是Binder,看下它的实现:

而像我们写的这个AIDL肯定不是这种情况,S端是在另一个进程,所以此时流程就会执行到这:

也就是返回了一个代理对象,里面包含IBinder,注意这个IBinder其实是:

而Proxy长啥样呢?

好,咱们来验证一下看是否拿到的就是Proxy,修改一下咱们上一次的小案例:

嗯,确实是,也就是最终咱们调用的这些:

都调用的是Proxy中的方法了:

那是不是这里也能论证之前咱们所说的理论,Proxy是跟客户端通讯的,也就是Client中调用addPerson()方法,先往IBinder来写数据,大概瞅一眼:

然后开始往Parcel对象开始写数据了:

接着就比较核心了:

一猜都能猜到,跨进程通信就靠它了,细看一下:

然后由于这个方法木有返回值所以木有返回,则看是否发生异常了:

而我们还定义了另一个AIDL方法,它是有返回值,所以在transact之后会有一个值的读取动作,瞅一下:

目前已经将数据写到IBinder了,接下来则是IBinder往服务端写数据了,此时其实流程就会到这:

这时就会调用Stub的onTransact方法了,如下:

咱们具体来看一下是怎么来执行的,首先会进行验证:

然后再调用服务端自己的方法:

,也就是咱们在服务端这里写的:

最后则写结果给IBinder:

然后客户端就可以读结果了,如下:

所以我们在调用远程的方法时可能会抛异常,在我们调用时就可以发现会要去try..catch..,如下:

以上就是关于AIDL进程间通讯的整体流程的梳理,不过这里缺少底层源代码的剖析,还不够细致,也就是说我们对于整个Binder通讯的大致流程是清楚了但是对于它在Android中的底层代码实现细节却一知半解,所以接下来则通过系统底层彻底的再来梳理一遍。

根据AIDL彻底梳理流程【分析系统源码】:

这里咱们以“android5.1.1”的源码进行分析,9.0的待之后再来进行梳理,先将低版本的原理梳理清楚,应该整个机制大体差不多,这里先提前将相关的代码导到工程中以便进行分析:

这个过程分析起来是比较复杂的,需要有耐心,理解透了对咱们的技能提升是有质的飞跃的,所以再复杂这花的时间也是值得的。那咱们从哪分析起呢?直接从我们应用的角度出发,在使用时会先bindService,如下:

所以点击进去看一下它的具体系统的实现:

我们知道最终Context的实现类是ContextImpl,所以定位到ContextImpl:

此时再定位到bindServiceCommon方法,里面代码比较多只看核心:

先来瞅一下ActivityManagerNative类:

再看一下IActivityManager接口:

跟啥类似呢?咱们来瞅一下自己编写的AIDL生成的代码:

而且还看个东东就能秒懂的:

这不也就是一个AIDL的Binder通信嘛,只是说这个是由Google工程师自己编写的,而我们使用的是编译器自动生成的,了解到这个本质非常之重要,因为我们平常使用的大量的Activity中的方法其实都是用的Binder机制来进行通讯的,比如:

其实底层是一个C/S的通讯,这个在之后的其它系统源中码会大量用到,好,下面回到主流程,再来找一下它中的getDefault()方法:

看gDefault是啥呢?瞅一下:

那看一下里面的create()的实现:

这里再说一个这个ServiceManager架构设计层面的东东,对于Android中的各个APP,每个APP都需要用到系统的一些服务,那不可能每个APP都自己去实现这些系统服务,而应该是有一个统一的系统服务器管理中心,当app需要这些服务器则通过这个管理中心去拿,画个简图如下:

而每个具体系统服务肯定是在另外单独的进程中,应用一启动都会向ServiceManager中进行注册,也就是如上一次所分析的将IBinder引用注册到了ServiceManager当中了,而当APP需要某些系统服务时,则需要通过ServiceManager.getService("xxx")来获取IBinder引用进而来实现整个跨进程的系统服务器通讯,整个就是典型的Binder调用的过程。那有了IBinder引用之后 ,则需要获取真正的对象那不还是跟咱们写的一样,如:

所以回到咱们的流程中就可以看到,获得了IBinder引用之后,则接下来就是调用它了:

好,继续回到主流程继续分析,接着就得来分析它了:

由于AcitivityManagerNative.getDefault()返回的是IActivityManager,所以得去找它的实现类,它的具体实现类其实是经典的ActivityManagerService:

所以,最终会调到这:

发现绑定的流程又要进行中断了,这里的mServices是啥呢?

所以,流程继续中转,转到ActivityServices.bindServiceLocked(),接下来流程就比较重要了,代码量也比较多,需要打起精神:

当然还是分析主流程:

也就是:

然后继续:

然后跟进去瞅一眼,看是如何绑定服务的:

其中r是ServiceRecord,app是ProcessRecord,而thread是IApplicationThread:

而它的具体实现类是在这:

所以再来找它里面的scheduleBindService()方法:

而谈到ActivityThread我们就非常之熟悉了,里面有一个mH的Handler,里面处理了大量的系统消息,这里来找一下BIND_SERVICE的消息,看它的处理细节:

好,接下来研究下它内部的细节:

啥意思,回到咱们写的案例上来理解,也就是咱们服务端编写的Service:

为啥这么肯定,咱们再来理解一下它的赋值就秒懂了:

对于服务的创建最终会执行到ActivityThread.handleCreateService()来,具体流程就不多分析了,这里来看一下我们想看的:

那很显然这个服务肯定是咱们编写的服务端的服务嘛:

到这里咱们得将之前的图修改一下:

那。。这个IBinder引用是如何返回到客户端的呢?好,接下来继续回到主流程:

也就是:

至此!!整个绑定服务及最终将IBinder引用给返回给客户端的完整流程就已经分析到了,真还是挺复杂的。。

好,接下来再来讨论一个细节问题:

这里就找到Proxy类以其中的一个方法来例:

而根据我们上一节中的底层分析,Binder驱动底层是由C++来实现的,所以肯定会用到ndk,那咱们瞅一下看是不是:

最终就会看到NDK的身影:

至于底层就不看了,这是往Binder写数据的流程,接着就调用服务端的这个回调方法,最终调用到服务端的方法,如下:

好,还有个细节就是说IBinder引用什么时候会放到共享内存呢?也就是:

其实是这样的:

然后会去调用Binder的无参构造,那就看一下它的无参构造实现:

也就是只要创建咱们的IBinder,则会通过NDK来注册到底层的Binder驱动中。整个Binder机制就分析到这了,通过这两篇的梳理,对于Android Binder机制有了一个本质认识,这对于咱们不管是面试还是说实际工作意义都是非常大的。

Android Binder机制彻底梳理二的更多相关文章

  1. Android Binder机制彻底梳理一

    Binder架构图: 先来瞅一下它的整体架构图: 其中粉红部分是上层的Binder,而蓝色的则是下层的Binder,很显然上层的是依赖于下层的. 什么是Binder[有个大概了解]? 这里从几个层面来 ...

  2. 【转】Android - Binder机制

    以下几篇文章是分析binder机制里讲得还算清楚的 目录 1. Android - Binder机制 - ServiceManager 2. Android - Binder机制 - 普通servic ...

  3. Android Binder机制简单了解

    Binder -- 一种进程间通信(IPC)机制, 基于OpenBinder来实现 毫无疑问, 老罗的文章是不得不看的 Android进程间通信(IPC)机制Binder简要介绍和学习计划 浅谈Ser ...

  4. ANDROID BINDER机制浅析

    Binder是Android上一种IPC机制,重要且较难理解.由于Linux上标准IPC在灵活和可靠性存在一定不足,Google基于OpenBinder的设计和构想实现了Binder. 本文只简单介绍 ...

  5. 浅谈android binder机制

    binder机制 是谷歌优化在android上更适合终端的IPC(多进程通信方式),满足系统对通信方式,传输性能和安全性的要求. 特性: 1. 用驱动程序来推进进程间的通信.2. 通过共享内存来提高性 ...

  6. android binder机制之——(创建binder服务)

      Binder机制编程 前面的几篇文章具体介绍了android中binder机制的方方面面,相信你对binder机制已经有了较深刻的理解.俗话说得好"学以致用",以下我们就通过在 ...

  7. Android Binder机制详解:手写IPC通信

    想要掌握一样东西,最好的方式就是阅读理解它的源码.想要掌握Android Binder,最好的方式就是写一个AIDL文件,然后查看其生成的代码.本文的思路也是来自于此. 简介 Binder是Andro ...

  8. Android binder机制---概述

    1.进程间通讯的原因 目前操作系统都使用虚拟存储技术,管理内存. 假设是32位机器,0-3G是用户空间,3-4G是系统使用.虚拟内存和逻辑内存都按4K分页.这样虚拟内存和逻辑内存就存在对应关系. 一个 ...

  9. android binder机制详解

    摘要 Binder是android中一个很重要且很复杂的概念,它在系统的整体运作中发挥着极其重要的作用,不过本文并不打算从深层次分析Binder机制,有两点原因:1是目前网上已经有2篇很好的文章了,2 ...

随机推荐

  1. 一台Linux服务器(4C8G配置)可以负载百万个连接?

    一台Linux服务器可以负载多少个连接? 首先我们来看如何标识一个TCP连接?系统是通过一个四元组来识别,(src_ip,src_port,dst_ip,dst_port)即源IP.源端口.目标IP. ...

  2. CentOS忘记密码修改方案以及centos卡在开机登录界面,命令失效的解决方法

    CentOS忘记密码修改方案 应用场景 linux管理员忘记root密码,需要进行找回操作. 注意事项:本文基于CentOS7.2环境进行操作的,由于CentOS的版本之间是有差异的,继续之前请先确定 ...

  3. AQS1---走向稳定态

    AQS的思想(稳定思想):即使确定了正常节点,这个节点也可能下一秒异常,即使找到了正常节点,这个节点可能只是异常status=0/-1的节点,这些都不要紧,都只是在自己旋转‘生命周期’里面和自己所看到 ...

  4. MODBUS 数据格式相关记录

    串口通讯格式: 串口通讯可以分为同步通讯(Synchronous)和异步通讯(Asynchronous).同步通讯时有一根时钟信号,数据格式中没有起始位和停止位:异步通讯中没有时钟信号,数据格式中包含 ...

  5. Win 10卡顿怎么办?解决win10卡顿的方法大汇总

    最近微软开始向Windows 10用户推送创造者更新(Creators Update),相信也有很多小伙伴已经尝鲜了这一最新的版本.而对于win10的使用体验,很多小伙伴第一个抱怨的问题便是win10 ...

  6. 【题解】选数字 [51nod1354]

    [题解]选数字 [51nod1354] 传送门:选数字 \([51nod1354]\) [题目描述] 共 \(T\) 组测试点,每一组给定一个长度为 \(n\) 的序列和一个整数 \(K\),找出有多 ...

  7. 『金字塔 区间dp』

    金字塔 Description 虽然探索金字塔是极其老套的剧情,但是这一队 探险家还是到了某金字塔脚下.经过多年的研究,科 学家对这座金字塔的内部结构已经有所了解.首先, 金字塔由若干房间组成,房间之 ...

  8. 《PHP7底层设计与源码实现》学习笔记1——PHP7的新特性和源码结构

    <PHP7底层设计与源码实现>一书的作者陈雷亲自给我们授课,大佬现身!但也因此深感自己基础薄弱,遂买了此书.希望看完这本书后,能让我对PHP7底层的认识更上一层楼.好了,言归正传,本书共1 ...

  9. 探索ASP.NET MVC5系列

    探索ASP.NET MVC5系列之~~~6.Session篇(进程外Session)     探索ASP.NET MVC5系列之~~~5.缓存篇(页面缓存+二级缓存)     探索ASP.NET MV ...

  10. webbrowser实现一个进程一个代理的办法

    public static void RefreshIESettings(string strProxy) { const int INTERNET_OPTION_PROXY = 38; const ...