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 }

    

    

原文地址:https://www.cnblogs.com/naray/p/8795909.html