一、简介
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 }