很长时间没有些文章了,有时候很想写一点东西,但是又不知道写什么,刚好这段时间离职的空闲时间,就简单的写一些东西吧;
1. 什么是Binder?
2. Binder流程分析;
3. Binder应用层代码验证流程;
一. Binder是Android中跨进程通信的一种手段,在Android中,大多数情况下,一个进程就是一个应用,所以Binder也可以用来两个应用之间的通信;
二. Binder的流程分析,这里我想使用一张图来描述:
通过上面的流程,完成了,从应用A调用应用B的show方法并且返回了一个返回值1;
上面的流程我们要注意:
上面的过程是通过Android 操作系统建立好连接后,应用A和应用B通信流程;
应用A和应用B的Binder是一模一样的,什么意思:就是说包名+类名,以及类里面的源码都是一样的
应用A和应用B的Binder其实是两个不同的对象,因为在内存是不一样的,因为是两个进程,虚拟机都不一样,虚拟机分配的地址也不一样
由于Binder的特殊性,即使不一样,系统也会认为是一样的。
三. 代码去验证:
核心代码简要:
MyBinder接口里面的代码:
interface MyBinder extends android.os.IInterface {
//这里的IInterface类似于 Serializable 接口是一个标志的接口,用来让系统知道,这个是Binder相关的类;
int show();
}
//这里的stub就是一个Binder对象,同时这个binder对象实现了MyBinder的一个接口,
public static abstract class Stub extends android.os.Binder implements com.andy.aidldemo.MyBinder {
//descriptor是一个Binder的一个唯一标识能通过这个标志找到这个类的内存地址
private static final java.lang.String DESCRIPTOR = "com.andy.aidldemo.MyBinder";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
//将DESCRIPTOR与Binder进行一个绑定的操作,类似id;
this.attachInterface(this, DESCRIPTOR);
}
/**
* 当应用A和应用B建立完成连接的时候,就会调用这个方法,
*
*/
public static com.andy.aidldemo.MyBinder asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
//通过这个IBinder对象,来查找本地内存是否有IInterface 这个对象,如果有直接返回;
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.andy.aidldemo.MyBinder))) {
return ((com.andy.aidldemo.MyBinder) iin);
}
//本地找不到就创建一个这样的类;
return new com.andy.aidldemo.MyBinder.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
//这里要注意的一个操作是这是一个响应端的执行方法,也就对应着上面流程图的应用B
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
//这里通过标志位,响应端执行对应的方法;
switch (code) {
case INTERFACE_TRANSACTION: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_show: {
data.enforceInterface(DESCRIPTOR);
//调用响应端(应用B)的show方法
int _result = this.show();
reply.writeNoException();
//将执行show方法返回的结果传递给Android操作系统
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
//这里是show方法的标志位;
static final int TRANSACTION_show = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
//上面是建立连接之后,在本地内存找不到对应的类的话,就创建这个类
private static class Proxy implements com.andy.aidldemo.MyBinder {
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;
}
//我们拿到这个类之后,调用的方法实际实际上是这个;
@Override
public int show() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
//建立远程的连接,传递标记为和参数,响应结果
mRemote.transact(Stub.TRANSACTION_show, _data, _reply, 0);
_reply.readException();
//从响应的结果中将show方法的返回值带出来;
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
}