最近学习理解android 中跨进程通信中的aidl和Binder这块知识点,定义上参考了《Android Bander设计与实现 - 设计篇》,
实际场景参考了《android开发艺术探索》和Android中为什么主线程不会因为Looper.loop()里的死循环卡死?,因为单纯看书实在太难直接理解,所以结合代码、设计原理以及讲解,边理解边梳理,框架图来自上方链接:
可以看一下android中实际的交互场景,图片来自Android中为什么主线程不会因为Looper.loop()里的死循环卡死?
图二:
Binder是跨进程(IPC Inter-Process-Communication )通信的一种手段,涉及的核心相关类有IBinder、Binder、Parcel、Parcelable其中Parcelable接口规定了对象序列化和反序列化的规范(转化成二进制),Parcel是Parcelable对象的载体。
以App运行这样一个实际场景为例,
ActivityManagerProxy是一个继承了Binder的abstract类,实现了IActivityManager接口,
而IActivityManager继承了IInterface接口,Binder本身是一个IBinder接口的实现,同样的还有BinderProxy类,在BinderProxy中有这样一段注释:
/**
* Java proxy for a native IBinder object.
* Allocated and constructed by the native javaObjectforIBinder function. Never allocated
* directly from Java code.
*
* @hide
*/
所以可知,android中Binder在java层的实现本质是一个服务端进程代理,例如ActivityManagerService和ApplicationThread,具体来看的话,ActivityManagerService继承了ActivityManagerNative,ActivityManagerNative继承自Binder实现了IActivityManager,IActivityManager是继承自IInterface接口的接口,ApplicationThread继承了ApplicationThreadNative而ApplicationThreadNative继承了Binder实现了IApplicationThread,IApplicationThread是一个继承IInterface接口的接口
IBinder中有具体的transact()方法和onTransact()方法,
/**
* Perform a generic operation with the object.
*
* @param code The action to perform. This should
* be a number between {@link #FIRST_CALL_TRANSACTION} and
* {@link #LAST_CALL_TRANSACTION}.
* @param data Marshalled data to send to the target. Must not be null.
* If you are not sending any data, you must create an empty Parcel
* that is given here.
* @param reply Marshalled data to be received from the target. May be
* null if you are not interested in the return value.
* @param flags Additional operation flags. Either 0 for a normal
* RPC, or {@link #FLAG_ONEWAY} for a one-way RPC.
*
* @return Returns the result from {@link Binder#onTransact}. A successful call
* generally returns true; false generally means the transaction code was not
* understood.
*/
public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
throws RemoteException;
transact()方法是用户端通过服务端Binder暴露的引用IBinder调用服务端暴露的IInterface接口的方法时会执行的,主要作用是把需要调用的服务端方法和相应的参数以二进制的形式封装到Parcel 变量名为data的参数中,通常Binder的transact()方法是同步的,对应的回调是onTransact(),在onTransact()方法中会通知客户端进行相应的处理。
/**
* Default implementation rewinds the parcels and calls onTransact. On
* the remote side, transact calls into the binder to do the IPC.
*/
public final boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply,
int flags) throws RemoteException {
if (false) Log.v("Binder", "Transact: " + code + " to " + this);
if (data != null) {
data.setDataPosition(0);
}
boolean r = onTransact(code, data, reply, flags);
if (reply != null) {
reply.setDataPosition(0);
}
return r;
}
Parcel的setDataPosition()方法中可以看到实际执行的是Parcel的native方法 nativeSetDataPosition(mNativePtr, pos),之后便是调用onTransact().
ActivityManagerService和ApplicationThread对应BookManagerService的例子的话,就是android生成的IBookManager.Stub类
对于android 来说四大组件的Service在IPC中扮演了客户端的角色,而常见的WindowManagerService,ActivityManagerService等存在于system_server进程中的服务则扮演了服务端的角色,他们之间常见的是通过aidl进行通信的