zoukankan      html  css  js  c++  java
  • Android-Binder机制

    http://www.jianshu.com/p/af2993526daf

    https://www.jianshu.com/u/e347b97e2f0c

    上面这篇文章讲得很清楚。以下我的一些理解:

    还是先说应用再说原理。

    1.应用

    以AIDL远程service为例,整个过程是这样的:

    1. 服务端定义AIDL文件,里面包含想提供给客户端的函数定义
    2. rebuild自动生成一个接口文件
    3. 服务器端定义自己的service,初始化stub实现函数,在onbind()返回stub
    4. 服务器端startService()
    5. 客户端实现ServiceConnection类并在其中调用函数
    6. 客户端bindService()

    2.原理

    Binder机制跨进程原理

    binder机制实现跨进程的思路是:

    1. 先有一个serviceManager负责管理所有的service
    2. 实现服务器端,然后向SM注册,说明我有什么功能,接受远程调用
    3. 客户端向SM查询xx进程里的xx对象
    4. SM向客户端返回一个对象代理
    5. 客户端把想做的事告诉对象代理
    6. 对象代理把数据转交给Binder驱动(SM)
    7. Binder驱动把数据给服务器,叫他做这个事
    8. 服务器把结果返回给Binder驱动,驱动再返回给客户端

    在实现上这些步骤是怎么样的,源码可以看一开始的链接,这边依旧是给我的理解。

    概念:

    IBinder/IInterface/Binder/BinderProxy/Stub

    我们使用AIDL接口的时候,经常会接触到这些类,那么这每个类代表的是什么呢?

    • IBinder是一个接口,它代表了一种跨进程传输的能力;只要实现了这个接口,就能将这个对象进行跨进程传递;这是驱动底层支持的;在跨进程数据流经驱动的时候,驱动会识别IBinder类型的数据,从而自动完成不同进程Binder本地对象以及Binder代理对象的转换。
    • IBinder负责数据传输,那么client与server端的调用契约(这里不用接口避免混淆)呢?这里的IInterface代表的就是远程server对象具有什么能力。具体来说,就是aidl里面的接口。
    • Java层的Binder类,代表的其实就是Binder本地对象。BinderProxy类是Binder类的一个内部类,它代表远程进程的Binder对象的本地代理;这两个类都继承自IBinder, 因而都具有跨进程传输的能力;实际上,在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。
    • 在使用AIDL的时候,编译工具会给我们生成一个Stub的静态内部类;这个类继承了Binder, 说明它是一个Binder本地对象,它实现了IInterface接口,表明它具有远程Server承诺给Client的能力;Stub是一个抽象类,具体的IInterface的相关实现需要我们手动完成,这里使用了策略模式。

    下面就是实现的流程:

    在AIDL接口文件中我们会写提供使用的函数定义,假设AIDL中的接口名称为A。方法为ADD,rebuild后自动生成的代码结构是这样的:

    • A接口继承IInterface(提供远程server对象具有什么能力)
    • ADD()
    • 内部stub类继承Binder

    内部stub类结构:

    • asInterface(),判断是否远程,返回Binder或新创建的BinderProxy
    • OnTransact(),接收Binder驱动发来的数据,调用相应函数,将结果返回给驱动
    • 内部Proxy类

    内部Proxy类结构:

    • ADD(),接收客户端数据,把数据序列化,调用transact()把数据发给Binder驱动,然后挂起等待Binder驱动返回的数据

    步骤一先不谈

    步骤二:实现服务器端,然后向SM注册,说明我有什么功能,接受远程调用

    这里包括

    • 定义AIDL接口并rebuild
    • 在AndroidManifest注册
    • 自定义service,实现stub中的函数
    • 启动service

    步骤三:客户端向SM查询xx进程里的xx对象

    步骤四:SM向客户端返回一个对象代理

    • 客户端实现ServiceConnection
    • 调用asInterface(),判断是否远程,返回Binder或新创建的BinderProxy。这里是BinderProxy

    步骤五:客户端把想做的事告诉对象代理

    步骤六:对象代理把数据转交给Binder驱动(SM)

    • 调用BinderProxy里的函数,调用transact()把数据发给Binder驱动,然后挂起等待Binder驱动返回的数据

    步骤七:Binder驱动把数据给服务器,叫他做这个事

    步骤八:服务器把结果返回给Binder驱动,驱动再返回给客户端

    • 调用OnTransact(),接收Binder驱动发来的数据,调用相应函数,将结果返回给驱动

    系统服务进程之间的通信

    http://www.jianshu.com/p/9b8e787a9bd3

    总体思路:

    再去翻阅系统的ActivityManagerServer的源码,就知道哪一个类是什么角色了:

    IActivityManager是一个IInterface,它代表远程Service具有什么能力

    ActivityManagerNative指的是Binder本地对象(类似AIDL工具生成的Stub类),这个类是抽象类,它的实现是ActivityManagerService;因此对于AMS的最终操作都会进入ActivityManagerService这个真正实现;

    同时如果仔细观察,ActivityManagerNative.java里面有一个非公开类ActivityManagerProxy, 它代表的就是Binder代理对象;是不是跟AIDL模型一模一样呢?那么ActivityManager是什么?他不过是一个管理类而已,可以看到真正的操作都是转发给ActivityManagerNative进而交给他的实现ActivityManagerService完成的。

  • 相关阅读:
    atitit.TokenService v3 qb1 token服务模块的设计 新特性.docx
    Atitit attilax在自然语言处理领域的成果
    Atitit 图像清晰度 模糊度 检测 识别 评价算法 原理
    Atitit (Sketch Filter)素描滤镜的实现  图像处理  attilax总结
    atitit。企业的价值观 员工第一 vs 客户第一.docx
    Atitit 实现java的linq 以及与stream api的比较
    Atitit dsl exer v3 qb3 新特性
    Atititi tesseract使用总结
    Atitit 修改密码的功能流程设计 attilax总结
    atitit.TokenService v3 qb1  token服务模块的设计 新特性.docx
  • 原文地址:https://www.cnblogs.com/qlky/p/6720405.html
Copyright © 2011-2022 走看看