知识要点:
1. Binder通信机制的架构
2. 实现进程间通信 的步骤
3. 完整的Binder通信过程
4. Binder驱动的内核 空间和用户空间的数据传输
5. AIDL工具的原理
6. Binder通信过程中进程和 线程的切换,什么是Binder线程
应用实现进程间通信的类图
应用发起进程间通信调用的流程图
AIDL文件编译生成后的java文件
package com.xiaopeng.montecarlo.root;
// Declare any non-default types here with import statements
public interface IMyAidlInterface extends android.os.IInterface {
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
public void interfaceA(int type) throws android.os.RemoteException;
public void interfaceB(int type) throws android.os.RemoteException;
/**
* Local-side IPC implementation stub class.
* 表示服务端的内部类Stub
*/
public static abstract class Stub extends android.os.Binder implements com.xiaopeng.montecarlo.root.IMyAidlInterface {
static final int TRANSACTION_interfaceA = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_interfaceB = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
private static final java.lang.String DESCRIPTOR = "com.xiaopeng.montecarlo.root.IMyAidlInterface";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.xiaopeng.montecarlo.root.IMyAidlInterface interface,
* generating a proxy if needed.
*/
public static com.xiaopeng.montecarlo.root.IMyAidlInterface asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.xiaopeng.montecarlo.root.IMyAidlInterface))) {
return ((com.xiaopeng.montecarlo.root.IMyAidlInterface) iin);
}
return new com.xiaopeng.montecarlo.root.IMyAidlInterface.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
java.lang.String descriptor = DESCRIPTOR;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(descriptor);
return true;
}
case TRANSACTION_interfaceA: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
this.interfaceA(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_interfaceB: {
data.enforceInterface(descriptor);
int _arg0;
_arg0 = data.readInt();
this.interfaceB(_arg0);
reply.writeNoException();
return true;
}
default: {
return super.onTransact(code, data, reply, flags);
}
}
}
//表示客户端的内部类Proxy
private static class Proxy implements com.xiaopeng.montecarlo.root.IMyAidlInterface {
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote) {
mRemote = remote;
}
@Override
public android.os.IBinder asBinder() {
return mRemote;
}
public java.lang.String getInterfaceDescriptor() {
return DESCRIPTOR;
}
/**
* Demonstrates some basic types that you can use as parameters
* and return values in AIDL.
*/
@Override
public void interfaceA(int type) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(type);
mRemote.transact(Stub.TRANSACTION_interfaceA, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
@Override
public void interfaceB(int type) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(type);
mRemote.transact(Stub.TRANSACTION_interfaceB, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
}
}
}
推荐资料:
Android Binder
深入理解Android内核思想
系统调用函数mmap和内核驱动mmap之间的联系与区别以及mmap原理详解以及实现内核用户空间之间的共享内存
“总而言之,常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,
1、mmap的关键点是实现了用户空间和内核空间的数据直接交互而效率更高。
2、mmap还提供了两个进程间共享内存及相互通信的一种方式。同时,如果进程A和进程B都映射了区域C,当A第一次读取C时通过缺页从磁盘复制文件页到内存中;但当B再读C的相同页面时,虽然也会产生缺页异常,但是不再需要从磁盘中复制文件过来,而可直接使用已经保存在内存中的文件数据。
3、可用于实现高效的大规模数据传输。内存空间不足,是制约大数据操作的一个方面,解决方案往往是借助硬盘空间协助操作,补充内存的不足。但是进一步会造成大量的文件I/O操作,极大影响效率。这个问题可以通过mmap映射很好的解决。换句话说,但凡是需要用磁盘空间代替内存的时候,mmap都可以发挥其功效。”
总结:
1. Binder机制基于Client/Service架构
2. Binder机制由Client端、Service端、Service Manager、Binder驱动构成,所以的Binder服务必须向Service Manager注册,Service Manager本身就是一个Binder服务。
3. AIDL将Binder的实现标准化,帮助快速生成客户端和服务端的实现方法。服务端需定义好提供给外部的接口文件.AIDL,编译后即生成Binder服务的实现和客户端的调用类,并在服务端继承该新生成类的内部抽象类:Stub,实现定义好的接口。然后把接口文件拷贝到客户端。
4. 该类是一个interface,继承于android.os.IInterface。其中有静态抽象类Stub继承于Binder并实现服务接口,客户端通过先要向ServiceManager查询所要调用的服务,ServiceManager返回注册过的Binder句柄,然后通过客户端通过Stub.asInterface方法得到该服务的Proxy代理类,在该类中会将客户端对服务接口的调用通过Binder.transact方法转换到Binder驱动的内核调用,继而转换到该接口服务端的Stub.onTransact调用到具体实现,并通过Binder驱动将结果返回
5. Binder驱动的实现原理是基于mmap,mmap只需要禁行一次拷贝,效率更高,实现了用户空间和内核空间的直接数据传递。他为每个Binder服务维护一个Binder线程和相应的上下文信息。