之前写完了关于View的测量、布局和绘制以及事件的分发,思前想后还是决定要写下关于Binder的理解。提笔容易落笔难,写了几个字就不知道该如何写下去,干脆就这样结束吧(滑稽)。
1. 进程间通信(IPC)
我们都知道Android的Application运行在DVM上,当我们的APP启动时会由Zygote孵化一个新的进程作为APP的进程,所有的APP都独立运行在自己的进程中,他们之间的通信就成了问题。而Binder作为进程间通信的机制则解决了这个问题,Binder由Client、Server、Service Manager和Binder驱动程序组成,其中Client、Server和Service Manager运行在用户空间,Binder驱动程序运行内核空间。其中,核心组件便是Binder驱动程序了,Service Manager提供了辅助管理的功能,Client和Server正是在Binder驱动和Service Manager提供的基础设施上,进行Client-Server之间的通信。网传神图:
2. AIDL(Android Interface Definition Language)
AIDL全称Android接口定义语言,其设计的目的就是实现进程间的通信。上面我们说Android的IPC是通过Binder机制解决的,AIDL可以理解为Binder的具体实现。当然,AIDL应该算是谷歌爸爸提供给我们的一个简单实现进程间通信的语言,它会由IDE编译后生成代码,大大减少了我们开发所需要的时间。当然了,也可以通过手动编写代码去实现进程间通信,好像API 25和之前的AMS就是手动去实现的,现在API 26已经改为AIDL实现。
3. AIDL的使用
首先说明下,这篇文章并不是AIDL的教程,这里就挑侧重点来说下:
- 默认支持的数据类型:
1.1 Java中的八种基本数据类型
1.2 String 类型和CharSequence类型
1.3 List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable
1.4 Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable - 导入其他数据类型:
2.1 实现Parcelable接口
2.2 相同包下创建相同名称的AIDL文件
2.3 import相应的类型,并且作为参数时需要使用in、out、inout来修饰 - in、out、inout:
3.1 参数前面加上in作为修饰的话,代表当前参数作为流入参数,在这里可以修改对象的属性但不会影响原对象的值
3.2 参数前面加上out作为修饰的话,代表当前的参数作为流出参数,对象是一个属性值都是默认的对象,修改对象的属性会修改原对象属性的值
3.3 inout是in和out的综合体
关于Map:自己尝试的时候发现使用Map<Xxx,Xxxx>形式时会编译失败,改成Map即可。
4. AIDL的跨进程
AIDL文件定义好,编译一下IDE会自动生成关于AIDL的代码。我们可以从源码来看下究竟是如何跨进程的:
使用
调用方法
public interface IUserManager extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements com.nick.remoteservice.IUserManager {
private static final java.lang.String DESCRIPTOR = "com.nick.remoteservice.IUserManager";
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
public static com.nick.remoteservice.IUserManager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
// 通过描述查找是否为binder,如果不为空则判断是否实现了IUserManager接口
// 如果为空,则创建代理类
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.nick.remoteservice.IUserManager))) {
// 传入的就是我们的Stub对象(在service中初始化),我们可以直接调用方法
// 这时候没有涉及到进程间通信
return ((com.nick.remoteservice.IUserManager) iin);
}
// 代理类
return new com.nick.remoteservice.IUserManager.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
// 代理类通过transact方法调用onTransact方法
// 根据code来判断具体执行哪个操作
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
......
case TRANSACTION_addIn: {
data.enforceInterface(DESCRIPTOR);
com.nick.remoteservice.model.UserModel _arg0;
// 根据Parcel来反序列化对象
if ((0 != data.readInt())) {
_arg0 = com.nick.remoteservice.model.UserModel.CREATOR.createFromParcel(data);
} else {
_arg0 = null;
}
// 调用addIn方法,addIn方法的具体实现是在service中实现
com.nick.remoteservice.model.UserModel _result = this.addIn(_arg0);
reply.writeNoException();
// 写入结果
if ((_result != null)) {
reply.writeInt(1);
_result.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
} else {
reply.writeInt(0);
}
return true;
}
......
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.nick.remoteservice.IUserManager {
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 com.nick.remoteservice.model.UserModel addIn(com.nick.remoteservice.model.UserModel userModel) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
com.nick.remoteservice.model.UserModel _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((userModel != null)) {
_data.writeInt(1);
userModel.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
// native层调用transact方法,最终会调用Stub的onTransact方法,并将返回值写入_reply
mRemote.transact(Stub.TRANSACTION_addIn, _data, _reply, 0);
_reply.readException();
if ((0 != _reply.readInt())) {
// 序列化创建对象
_result = com.nick.remoteservice.model.UserModel.CREATOR.createFromParcel(_reply);
} else {
_result = null;
}
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
......
}
static final int TRANSACTION_addIn = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
......
}
public com.nick.remoteservice.model.UserModel addIn(com.nick.remoteservice.model.UserModel userModel) throws android.os.RemoteException;
......
}
上面的代码是由IDE通过AIDL自动生成的代码,我们可以看到:
- IDE生成了与我们定义的AIDL文件同名的java接口文件,并且该接口继承
IInterface
接口,同时该接口内部包括了抽象内部类Stub
(实现了该接口),Proxy
(代理类,同样实现了该接口并且方法全部实现) - 创建
Stub
类对象时需要实现我们在AIDL中定义的方法,需要在远端Service
中的onBind
方法中实现,通过bindService
方法中的ServiceConnection
来获得IBinder
实现类的引用,最终通过静态方法IUserManager.Stub.asInterface
将IBinder
实现类的引用生成Proxy
(远端调用的情况) -
asInterface
通过查找我们在创建对象是传入的描述(DESCRIPTOR)是否存在来判断是否为当前的Stub
对象,如果不是的话需要创建一个代理类Proxy
。 -
Proxy
类中的构造方法需要传入一个IBinder
的对象,当需要调用Server中的某个方法时会通过Proxy
调用远端Binder
对象的transact
方法,通过native层最终调用Stub
中的onTransact
方法,Stub
的onTransact
方法会根据传入的code
来判断需要调用哪个具体的方法,并且将结果写入Parcel
对象中。
流程图:
流程图
5. Debug证明
每次写文章都想要把每个地方都弄清楚,起码说能够自己这关过得去。所以,有时候写一篇文章需要找好多资料,看很多源码。最简单的证明流程是正确的我觉得就是Debug大法,下面看下debug下asInterface
的调用:
从上图中可以看到我们传入的
IBinder
实例是BinderProxy
,最终会创建一个Stub.Proxy
对象。这里说下Binder和BinderProxy:
public class Binder implements IBinder {}
final class BinderProxy implements IBinder {}
从名字上就可以知道:Binder是IBinder的具体实现,而BinderProxy作为Binder的代理类,可以通过BinderProxy调用Binder中的方法。
接着我们看下asInterface
的调用方法:
我们看到我们调用的是
LoadedApk$ServiceDispatcher$RunConnection
对象的run
方法:RunConnection
而
run
方法中调用了LoadedApk$ServiceDispatcher
的doConnected
方法:
public void doConnected(ComponentName name, IBinder service, boolean dead) {
......
// If there is a new service, it is now connected.
if (service != null) {
mConnection.onServiceConnected(name, service);
}
}
最终调用我们的onServiceConnected
方法。这里面的方法调用是在bindService
中调用的,其中创建IBinder
对象是在ActivityThread
中:
在这里也可以看到我们传入的
IBinder
对象是我们的RemoteService
匿名内部类,而我们通过ServiceConnection
获得的是BinderProxy对象,这里猜测:由于Service在一个新的进程中,所以由native层给我们返回了BinderProxy对象。native层的代码并不是很懂,但是我在查看Parcel
的writeStrongBinder
和readStrongBinder
方法中看到了关于BinderProxy
的创建,这里不多说。接着我们调用下远端Service的方法:
addIn
addIn
方法执行到mRemote.transact
方法接着会执行:onTransact
onTransact
最终调用Service
中的addIn
方法完成操作:Service中addIn方法
执行完成
6. native层分析(不是很了解,给自己写的)
关于Binder层的分析,有需要的还是去看老罗的讲解,非常详细。这里还是将自己探索的过程记录下(在线源码和在线全局源码全局搜索)。
我们知道我们写的AIDL生成的代码会继承Binder,所以在创建对象的时候会调用Binder的初始化:
public Binder() {
init();
......
}
private native final void init();
对应native层代码:
/frameworks/base/core/jni/android_util_Binder.cpp:
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
// gBinderOffsets是native层对java层Binder映射的结构体
// gBinderProxyOffsets是native层对java层BinderProxy映射的结构体
// 这里创建了JavaBBinderHolder对象,并将mObject对象设置成JavaBBinderHolder的地址
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
class JavaBBinderHolder : public RefBase
{
public:
// 重写了get方法,返回JavaBBinder
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};
可以看到,初始化的过程就是创建了一个JavaBBinderHolder
对象,并将对象的指针赋值给gBinderOffsets.mObject
。
关于gBinderOffsets:
/frameworks/base/core/jni/android_util_Binder.cpp:
static struct bindernative_offsets_t
{
// Class state.
jclass mClass;
jmethodID mExecTransact;
// Object state.
jfieldID mObject;
} gBinderOffsets;
// 各种方法
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
// 注册
static int int_register_android_os_Binder(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderPathName);
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
// 将execTransact的methodId赋值,最后就是调用此方法来调用java层的Binder对象的execTransact方法
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
// 这个mObject就是Binder的mObject的fieldId
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
接着我们会调用BinderProxy
的transact
方法:
/frameworks/base/core/jni/android_util_Binder.cpp:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
// code = 1(FIRST_CALL_TRANSACTION) flags = 0
......
// 获得BinderProxy,在这里是BpBinder(p代表proxy的意思)
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
......
// 调用BpBinder的transact方法
status_t err = target->transact(code, *data, reply, flags);
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
if (kEnableBinderSample) {
if (time_binder_calls) {
conditionally_log_binder_call(start_millis, target, code);
}
}
if (err == NO_ERROR) {
return JNI_TRUE;
} else if (err == UNKNOWN_TRANSACTION) {
return JNI_FALSE;
}
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
我们看到这里获取了gBinderProxyOffsets
的mObject
对象的值,作为IBinder
的指针(这里其实是BpBinder
)。接着调用了BpBinder
的transact
方法,下面看下gBinderProxyOffsets
和BpBinder
:
/frameworks/base/core/jni/android_util_Binder.cpp:
static struct binderproxy_offsets_t
{
// Class state.
jclass mClass;
// BinderProxy构造方法的方法Id
jmethodID mConstructor;
// BinderProxy的sendDeathNotice方法Id
jmethodID mSendDeathNotice;
// Object state.
// mObject的fieldId
jfieldID mObject;
// mSelf的fieldId
jfieldID mSelf;
// mOrgue的fieldId
jfieldID mOrgue;
} gBinderProxyOffsets;
// 各种方法
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
// 各种赋值操作
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
/frameworks/native/libs/binder/BpBinder.cpp:
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
// 调用了IPCThreadState的transact方法
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
我们可以看到BpBinder
调用了IPCThreadState
的transact
方法:
/frameworks/native/libs/binder/IPCThreadState.cpp:
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
......
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
// 写入数据
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
......
if ((flags & TF_ONE_WAY) == 0) {
......
if (reply) {
// 等待响应
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
......
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
} else if (statusBuffer) {
tr.flags |= TF_STATUS_CODE;
*statusBuffer = err;
tr.data_size = sizeof(status_t);
tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
tr.offsets_size = 0;
tr.data.ptr.offsets = 0;
} else {
return (mLastError = err);
}
//数据写入mOut
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
数据写入完成后就开始等待响应:
/frameworks/native/libs/binder/IPCThreadState.cpp:
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;
while (1) {
// 这里面会进行ioctl操作,不是很懂。。。
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = (uint32_t)mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
// cmd = BC_TRANSACTION,这里执行default
switch (cmd) {
......
default:
// 调用executeCommand方法
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
......
return err;
}
因为我们传入的是BC_TRANSACTION
命令,所以最后进入executeCommand
方法:
/frameworks/native/libs/binder/IPCThreadState.cpp:
status_t IPCThreadState::executeCommand(int32_t cmd)
{
BBinder* obj;
RefBase::weakref_type* refs;
status_t result = NO_ERROR;
switch ((uint32_t)cmd) {
......
case BR_TRANSACTION:
{
binder_transaction_data tr;
// 把之前写入out中的数据读取出来
result = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(result == NO_ERROR,
"Not enough command data for brTRANSACTION");
if (result != NO_ERROR) break;
Parcel buffer;
buffer.ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
const pid_t origPid = mCallingPid;
const uid_t origUid = mCallingUid;
const int32_t origStrictModePolicy = mStrictModePolicy;
const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;
mCallingPid = tr.sender_pid;
mCallingUid = tr.sender_euid;
mLastTransactionBinderFlags = tr.flags;
Parcel reply;
status_t error;
......
if (tr.target.ptr) {
//
if (reinterpret_cast<RefBase::weakref_type*>(
tr.target.ptr)->attemptIncStrong(this)) {
// 这里我认为会调用JavaBBinder的transact方法
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags);
reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
} else {
error = UNKNOWN_TRANSACTION;
}
} else {
error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
}
......
mCallingPid = origPid;
mCallingUid = origUid;
mStrictModePolicy = origStrictModePolicy;
mLastTransactionBinderFlags = origTransactionBinderFlags;
......
}
break;
......
}
......
return result;
}
紧接着会将我们写入的数据读取出来,并调用JavaBBinder
的transact
方法(没有重写此方法,所以调用BBinder
中的transact
方法):
/frameworks/native/libs/binder/Binder.cpp:
status_t BBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code) {
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}
if (reply != NULL) {
reply->setDataPosition(0);
}
return err;
}
最终调用``JavaBBinder``中的``onTransact``方法:
/frameworks/base/core/jni/android_util_Binder.cpp:
JavaBBinder:
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
// 调用Binder的execTransact方法
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
......
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
在JavaBBinder
中会执行env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
方法,了解JNI的话就会知道这里会调用方法id是mExecTransact的方法,这对应就是Binder
中的execTransact
方法:
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
// 根据内存地址生成数据
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
boolean res;
final boolean tracingEnabled = Binder.isTracingEnabled();
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
// 调用onTransact方法
res = onTransact(code, data, reply, flags);
} catch (RemoteException|RuntimeException e) {
......
} catch (OutOfMemoryError e) {
......
} finally {
......
}
checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
reply.recycle();
data.recycle();
StrictMode.clearGatheredViolations();
return res;
}
如我们所料,这里面调用了Binder的onTransact方法最终执行我们远端Service的方法,整个流程到这里就结束了。
7. 总结
对于native层我了解不是很多,这次算是硬着头皮一点点分析出来的(主要是想给自己说的过去的理由,不然根本不会写这篇文章),如果不分析native层的话,整个流程还是比较简单的:
- 客户端获取远端服务的代理,通过
IXxx.Stub.asInterface()
创建代理类。 - 客户端通过调用远端代理类的
transact
方法调用远端服务的具体方法。 - native层通过反射调用
Binder
类的execTransact
方法,最终调用Binder
类的onTransact
方法完成本次方法,并将结果写入reply
。 - 客户端通过
reply
来获取数据。
至此,整个流程已经完毕。
OK
网友评论