2.6基础知识-Binder

2018-11-09  本文已影响0人  205蚁

Binder详解

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

1.进程隔离/虚拟地址空间(进程A和进程B的虚拟地址空间不一样,独享)
2.概念:系统调用。进程只可以访问许可的资源,将Linux内核层和上层程序抽象分离开。用户可以通过系统调用,在用户空间访问内核的某些程序

3.binder驱动:android系统中,运行在内核空间中,负责各个用户进程通过binder通信的内核进行通信的交互模块叫binder驱动。
    驱动程序,一般指的是设备的驱动程序,可以使计算机和设备通信的特殊程序,也是一种软件,其实也是一种接口,操作系统可以通过这个接口操作并控制硬件设备;

2.Binder通信机制介绍

图1

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

3.AIDL实现(Binder的实例)

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

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

其中:

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方法
上一篇下一篇

猜你喜欢

热点阅读