美文网首页
2.6基础知识-Binder

2.6基础知识-Binder

作者: 205蚁 | 来源:发表于2018-11-09 08:14 被阅读0次

    Binder详解

    • 1 .Linux内核的基础知识(跟Binder有关的)
      1. Binder通信机制介绍
      1. AIDL实现

    1.Linux内核的基础知识(跟Binder有关的)

    1.进程隔离/虚拟地址空间(进程A和进程B的虚拟地址空间不一样,独享)
    2.概念:系统调用。进程只可以访问许可的资源,将Linux内核层和上层程序抽象分离开。用户可以通过系统调用,在用户空间访问内核的某些程序
    
    3.binder驱动:android系统中,运行在内核空间中,负责各个用户进程通过binder通信的内核进行通信的交互模块叫binder驱动。
        驱动程序,一般指的是设备的驱动程序,可以使计算机和设备通信的特殊程序,也是一种软件,其实也是一种接口,操作系统可以通过这个接口操作并控制硬件设备;
    

    2.Binder通信机制介绍

    • 1 .为什么要使用binder

        1. Android使用的Linux内核拥有着非常多的跨进程通信机制,管道,socket
          - 1. 性能上:广泛的通信机制对性能有严格的要求
          binder相对于socket更加高效
          - 2. 安全性上,传统通信对通信双方没有做出严格的验证,只有上层协议才做架构,binder对通信双方做身份校验,权限模型基础
      1. binder通信模型
          1. 通信录:binder驱动。
          1. 电话基站:serviceManager
    图1

    跨进程通信时:客户端只是持有了一个服务端的代理对象引用,具体的跨进程通信都是通过代理对象来协助完成的

    • 1 .到底什么事binder
      • 1 .通常意义下,Binder指的是一种通信机制
      • 2 .对于Server进程来说,Binder指的是Binder本地对象
        • 1 .对Client来说,Binder指的是Binder的代理对象
        • 2 .对处于同一个进程来说,客户端Binder也是本地对象
        • 3 . 客户端对象和服务端对象是无法交互的,只有使用binder通过ServiceManager才能交互
      • 3 .对于传输过程而言,Binder是可以进行跨进程传递的对象
        • binder驱动会对具有跨进程传入能力的对象(不是。。继承了PacexxBle,没搞清)做特殊处理,自动会完成对代理对象和服务端对象的转换
    • 3 . binder通信机制原理

    3.AIDL实现(Binder的实例)

    图2
    图3 图4 图5 图6 图7 图8 图9

    生成一个静态Stub类,继承android.os.Binder,实现本地定义的AIDL接口

    • 说明是一个Binder本地对象,具有远程服务端承诺给客户端远程传递数据的能力。
    • 又由于Stub这个抽象类是个抽象的,具体的实现需要自己来。这个是java中的一个策略模式。
    • 首先asInterface(android.os.IBinder obj):这是一个接口,代表了跨进程传输的能力,只要实现了这个接口就能将这个对象跨进程传递,驱动底层支持的,驱动会识别支持IBinder类型的数据

    其中:

    public static 自定义的AIDL接口名称 asInterface(android.os.IBinder obj){
            if(obj == null){return null;}
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPOR);
            if(((iin!=null)&&)(iin instanceof 自定义的AIDL接口名称))){
                return ((自定义的AIDL接口名称)iin)
            }
            return new 自定义的接口名称.Stub.Proxy(obj);
        }
        //如果是同一个进程的话就使用iin,如果不是同一个进程的话就会使用使用它的代理对象
    
        在这个Stub类中,实现了compute方法
        public int compute(int a,int b)throw android.os.RemoteException{
            android.os.Parcel _data = android.os.Parcel.obtain();
            android.os.Parcel _reply = android.os.Parcel.obtain();
            int _result;
            try{
                _data.writeInterfaceToken(DESCRIPTIOR);
                _data.writeInt(a);
                _data.write(b);
                mRemote.transat(Stub.TRANSACTION_compute,_data,_reply,0);
                _reply.readExcption();
                _result = _reply.readInt();
            }
            finally{
            _reply.recycle();
            _data_recycle();
            }
            return _result;
        
        }
        
        IBinder类中:
            public boolean transact(int code,Parcel data,Prarcel reply,int flags) throw RemoteException;
                其实是一个native层的方法,最终会调用到onTransat方法
        看Stub实现
            根据调用号,调用刚才写的compute跨进程调用方法
            public boolean onTransact(int code,android.os.Parcel data,android.os.Parcel reply,int flags)throw android.os.xxException{
                switch(code){
                    case INTERFACE_TRANSACTION:{
                        reply.writeString(DESCRIPTOR);
                    }
                    case TREANSACTION_compute:{
                        data.enforceInterface(DESCRIPTOR);
                        int _arg0;
                        _arg0 = data.readInt();
                        int _arg1;
                        _arg1 = data.readInt();
                        int _result = this.compute(_arg0,_arg1);
                        reply.writeNoException();
                        reply.writeInt(_result);
                        return true;
                    }
    
                }
                return super.onTransact(code,data,reply,flags);
                
    
            }
    
    1. 先用Parcel将数据序列化
    2. 然后调用transact方法,最终会调用的onTransat方法,然后根据调用号,调用到compute 自定义的AIDL方法

    相关文章

      网友评论

          本文标题:2.6基础知识-Binder

          本文链接:https://www.haomeiwen.com/subject/zohnxqtx.html