• Android Binder进阶扁一


    一、简介

      1. Linux内核基础知识,

      (1)进程隔离/虚拟地址空间

        进程隔离是防止进程A数据写入到进程B地址空间,进程隔离实现使用了虚拟地址空间。

        进程间通信需要使用某种相应的通信机制,在Android中使用Binder实现。

      (2)系统调用 (内核空间和用户空间)?

        对内核有某些保护机制来告诉应用程序只能访问许可的资源,而不许可的资源是不能被访问的。这也就是Linux把内核层和上层应用程序分隔开,也就是内核层和用户空间。用户可以通过系统调用在用户空间来访问内核的某些程序。

    二、Binder驱动

       在Android中Binder驱动是运行在内核空间的,它是负责各个用户进程通过Binder通信内核来进行同交互的模块就是Binder驱动。

    三、Binder通信机制

      (一)为什么使用Binder

        在Android中使用Linux内核,IPC通信有很多,在Android中为什么Binder驱动来完成进程间通信?

        1. 性能上,在移动设备上广泛使用跨进程通信,对通信机制本身有严格要求,而Binder比传统的Socket编程更加高效。

        2. 安全性上,在传统的进程间通信上对通信两方的身份没有严格的验证,只有上层协议才有完整的架构。比如:Socket通信的IP地址是人为填写的,IP地址可以伪造。而Binder机制从协议本身就支持通信双方进行身份较验,在这基础上提高了Android程序的安全性。并且Binder的身份较验也是Android中权限模型的基础。    

      (二)通信模型(C/S模式)

        1. Binder Service      

        2. Binder Client

        3. Binder 驱动

        4. Service Manager

       

      1. Service Manager建立,有一个进程向Binder驱动提出申请为Service Manager。Binder驱动通过申请后,Service Manager负责管理所有的Binder Server。

      2. Binder Server在Service Manager进行注册,在Service Manager建立一个表来保存注册的Binder Server。

      3. Binder Client向Service Manager中提出请求,想访问某一个Server。Service Manager在表中查找,找到相应的Server代理并返回给Client。

      PS:上图解释,Binder通信模型的三个步骤。

      Binder进程间通信:

      PS:重点是Client进程只是持有Server端代理对象引用,通过Server端的代理对象完成了Client进程与Server端的通信。Server端代理对象是通过Binder驱动进行包装的,而不是Server端的真实对象。

    四、总结

      什么Binder?

      1. Binder是一种进程间通信机制。

      2. 对于Server进程来说,Binder指的是Binder本地对象。而对于Client端来说Binder指的是Server端代理对象。

      3. 对于传输过程来说,Binder指的是可以进行跨进程间传递的对象。

    五、AIDL

      新建IMyAidlInterface.aidl文件

     1 // Declare any non-default types here with import statements
     2 
     3 interface IMyAidlInterface {
     4     /**
     5      * Demonstrates some basic types that you can use as parameters
     6      * and return values in AIDL.
     7      */
     8     void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
     9             double aDouble, String aString);
    10 }

      相对生成的源码为IMyAidlInterface.java文件

      1 // Declare any non-default types here with import statements
      2 
      3 public interface IMyAidlInterface extends android.os.IInterface {
      4     /**
      5      * Local-side IPC implementation stub class.
      6      */
      7     public static abstract class Stub extends android.os.Binder implements com.naray.IDALpdemo
      8             .IMyAidlInterface {
      9         private static final java.lang.String DESCRIPTOR = "com.naray.IDALdemo.IMyAidlInterface";
     10 
     11         /**
     12          * Construct the stub at attach it to the interface.
     13          */
     14         public Stub() {
     15             this.attachInterface(this, DESCRIPTOR);
     16         }
     17 
     18         /**
     19          * Cast an IBinder object into an com.naray.IDALdemo.IMyAidlInterface interface,
     20          * generating a proxy if needed.
     21          */
     22         public static com.naray.IDALdemo.IMyAidlInterface asInterface(android.os.IBinder obj) {
     23             if ((obj == null)) {
     24                 return null;
     25             }
     26             android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
     27             if (((iin != null) && (iin instanceof com.naray.IDALdemo.IMyAidlInterface))) {
     28                 return ((com.naray.IDALdemo.IMyAidlInterface) iin);
     29             }
     30             return new com.naray.IDALdemo.IMyAidlInterface.Stub.Proxy(obj);
     31         }
     32 
     33         @Override
     34         public android.os.IBinder asBinder() {
     35             return this;
     36         }
     37 
     38         @Override
     39         public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int
     40                 flags) throws android.os.RemoteException {
     41             switch (code) {
     42                 case INTERFACE_TRANSACTION: {
     43                     reply.writeString(DESCRIPTOR);
     44                     return true;
     45                 }
     46                 case TRANSACTION_basicTypes: {
     47                     data.enforceInterface(DESCRIPTOR);
     48                     int _arg0;
     49                     _arg0 = data.readInt();
     50                     long _arg1;
     51                     _arg1 = data.readLong();
     52                     boolean _arg2;
     53                     _arg2 = (0 != data.readInt());
     54                     float _arg3;
     55                     _arg3 = data.readFloat();
     56                     double _arg4;
     57                     _arg4 = data.readDouble();
     58                     java.lang.String _arg5;
     59                     _arg5 = data.readString();
     60                     this.basicTypes(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);
     61                     reply.writeNoException();
     62                     return true;
     63                 }
     64             }
     65             return super.onTransact(code, data, reply, flags);
     66         }
     67 
     68         private static class Proxy implements com.naray.IDALdemo.IMyAidlInterface {
     69             private android.os.IBinder mRemote;
     70 
     71             Proxy(android.os.IBinder remote) {
     72                 mRemote = remote;
     73             }
     74 
     75             @Override
     76             public android.os.IBinder asBinder() {
     77                 return mRemote;
     78             }
     79 
     80             public java.lang.String getInterfaceDescriptor() {
     81                 return DESCRIPTOR;
     82             }
     83 
     84             /**
     85              * Demonstrates some basic types that you can use as parameters
     86              * and return values in AIDL.
     87              */
     88             @Override
     89             public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double
     90                     aDouble, java.lang.String aString) throws android.os.RemoteException {
     91                 android.os.Parcel _data = android.os.Parcel.obtain();
     92                 android.os.Parcel _reply = android.os.Parcel.obtain();
     93                 try {
     94                     _data.writeInterfaceToken(DESCRIPTOR);
     95                     _data.writeInt(anInt);
     96                     _data.writeLong(aLong);
     97                     _data.writeInt(((aBoolean) ? (1) : (0)));
     98                     _data.writeFloat(aFloat);
     99                     _data.writeDouble(aDouble);
    100                     _data.writeString(aString);
    101                     mRemote.transact(Stub.TRANSACTION_basicTypes, _data, _reply, 0);
    102                     _reply.readException();
    103                 } finally {
    104                     _reply.recycle();
    105                     _data.recycle();
    106                 }
    107             }
    108         }
    109 
    110         static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
    111     }
    112 
    113     /**
    114      * Demonstrates some basic types that you can use as parameters
    115      * and return values in AIDL.
    116      */
    117     public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble,
    118                            java.lang.String aString) throws android.os.RemoteException;
    119 }

        

        

  • 相关阅读:
    [bzoj4197][Noi2015]寿司晚宴
    [bzoj3531][Sdoi2014]旅行
    [洛谷P1430]序列取数
    [洛谷P2044][NOI2012]随机数生成器
    [洛谷P2839][国家集训队]middle
    [洛谷P3937]Changing
    [bzoj3532][Sdoi2014]Lis
    [洛谷P2590][ZJOI2008]树的统计
    [洛谷P4311]士兵占领
    [洛谷P1879][USACO06NOV]玉米田Corn Fields
  • 原文地址:https://www.cnblogs.com/naray/p/8795909.html
Copyright © 2020-2023  润新知