Android Binder——通过AIDL探究Binder

作者: nick_young | 来源:发表于2017-12-29 11:17 被阅读92次

    之前写完了关于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之间的通信。网传神图:

    Binder

    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.1 Java中的八种基本数据类型
      1.2 String 类型和CharSequence类型
      1.3 List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable
      1.4 Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable
    2. 导入其他数据类型:
      2.1 实现Parcelable接口
      2.2 相同包下创建相同名称的AIDL文件
      2.3 import相应的类型,并且作为参数时需要使用in、out、inout来修饰
    3. 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.asInterfaceIBinder实现类的引用生成Proxy(远端调用的情况)
    • asInterface通过查找我们在创建对象是传入的描述(DESCRIPTOR)是否存在来判断是否为当前的Stub对象,如果不是的话需要创建一个代理类Proxy
    • Proxy类中的构造方法需要传入一个IBinder的对象,当需要调用Server中的某个方法时会通过Proxy调用远端Binder对象的transact方法,通过native层最终调用Stub中的onTransact方法,StubonTransact方法会根据传入的code来判断需要调用哪个具体的方法,并且将结果写入Parcel对象中。

    流程图:


    流程图

    5. Debug证明

    每次写文章都想要把每个地方都弄清楚,起码说能够自己这关过得去。所以,有时候写一篇文章需要找好多资料,看很多源码。最简单的证明流程是正确的我觉得就是Debug大法,下面看下debug下asInterface的调用:

    asInterface
    从上图中可以看到我们传入的IBinder实例是BinderProxy,最终会创建一个Stub.Proxy对象。
    这里说下Binder和BinderProxy:
    public class Binder implements IBinder {}
    final class BinderProxy implements IBinder {}
    

    从名字上就可以知道:Binder是IBinder的具体实现,而BinderProxy作为Binder的代理类,可以通过BinderProxy调用Binder中的方法。
    接着我们看下asInterface的调用方法:

    image.png
    我们看到我们调用的是LoadedApk$ServiceDispatcher$RunConnection对象的run方法:
    RunConnection
    run方法中调用了LoadedApk$ServiceDispatcherdoConnected方法:
    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中:

    image.png
    在这里也可以看到我们传入的IBinder对象是我们的RemoteService匿名内部类,而我们通过ServiceConnection获得的是BinderProxy对象,这里猜测:由于Service在一个新的进程中,所以由native层给我们返回了BinderProxy对象。native层的代码并不是很懂,但是我在查看ParcelwriteStrongBinderreadStrongBinder方法中看到了关于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));
    }
    

    接着我们会调用BinderProxytransact方法:

    /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;
    }
    

    我们看到这里获取了gBinderProxyOffsetsmObject对象的值,作为IBinder的指针(这里其实是BpBinder)。接着调用了BpBindertransact方法,下面看下gBinderProxyOffsetsBpBinder

    /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调用了IPCThreadStatetransact方法:

    /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;
    }
    

    紧接着会将我们写入的数据读取出来,并调用JavaBBindertransact方法(没有重写此方法,所以调用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层的话,整个流程还是比较简单的:

    1. 客户端获取远端服务的代理,通过IXxx.Stub.asInterface()创建代理类。
    2. 客户端通过调用远端代理类的transact方法调用远端服务的具体方法。
    3. native层通过反射调用Binder类的execTransact方法,最终调用Binder类的onTransact方法完成本次方法,并将结果写入reply
    4. 客户端通过reply来获取数据。

    至此,整个流程已经完毕。


    OK

    相关文章

      网友评论

        本文标题:Android Binder——通过AIDL探究Binder

        本文链接:https://www.haomeiwen.com/subject/dzwugxtx.html