binder-JAVA层机制

根据以前分析过的cpp代码,以及编写了JAVA层的代码,笔者画了一个图进行了分层java

JAVA中,RPC层的代码是直接经过aidl文件生成的,cpp部分是须要咱们本身编写的android

那么在JAVA中就存在两个问题,就是图中红色的部分git

client是如何发送数据给server的
Service是如何读取到数据,如何调用到onTransact函数的数组

经过这两个问题去分析源码,就能理解JAVA层的机制了cookie

client流程

既然咱们获取服务使用 ServieManager 的getService,咱们就分析它(不知道为何版本28这个类里面的返回都是null,估计在哪里作了什么骚操做了吧)app

public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return getIServiceManager().getService(name);
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }
复制代码

这个sCache就是一个HashMap
private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();ide

主要看 getIServiceManager函数

private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }
复制代码
public static final native IBinder getContextObject();
复制代码

getContextObject 是一个native方法,之后看到这个native,咱们就应该知道,它是调用cpp的代码,就是一个JNI调用过程测试

JNI的对应代码在哪?

这部分主要是分析JNI的函数是如何生成的,不想了解的也能够直接跳过ui

注册binder

在Android系统开机过程当中,Zygote启动时会有一个虚拟机注册过程,该过程调用 AndroidRuntime::startReg 方法来完成jni方法的注册(这部分分析来自gityuan)

在 AndroidRuntime.cpp 中

int AndroidRuntime::startReg(JNIEnv* env)
{
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    env->PushLocalFrame(200);
    //注册 gRegJNI是一个数组,记录全部须要注册的jni方法,其中有一项是REG_JNI(register_android_os_Binder)
    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    return 0;
}
复制代码

看看 register_android_os_Binder

int register_android_os_Binder(JNIEnv* env) {
    if (int_register_android_os_Binder(env) < 0)
        return -1;

    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;

    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
    ...
    return 0;
}
复制代码

看来须要一个一个看了

int_register_android_os_Binder 注册 Binder类的jni方法

static int int_register_android_os_Binder(JNIEnv* env) {
    //其中kBinderPathName = "android/os/Binder";查找kBinderPathName路径所属类
    jclass clazz = FindClassOrDie(env, kBinderPathName);

    //将Java层Binder类保存到mClass变量
    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    //将Java层execTransact()方法保存到mExecTransact变量;
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
    //将Java层mObject属性保存到mObject变量
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

    //注册JNI方法
    return RegisterMethodsOrDie(env, kBinderPathName, gBinderMethods,
        NELEM(gBinderMethods));
}
复制代码

gBinderOffsets 是什么

static struct bindernative_offsets_t {
    jclass mClass; //记录Binder类
    jmethodID mExecTransact; //记录execTransact()方法
    jfieldID mObject; //记录mObject属性

} gBinderOffsets;
复制代码

gBinderOffsets保存了Binder.java类自己以及其成员方法execTransact()和成员属性mObject,这为JNI层访问Java层提供通道。另外经过查询获取Java层 binder信息后保存到gBinderOffsets,而再也不须要每次查找binder类信息的方式能大幅度提升效率,是因为每次查询须要花费较多的CPU时间,尤为是频繁访问时,但用额外的结构体来保存这些信息,是以空间换时间的方法

gBinderMethods

static const JNINativeMethod gBinderMethods[] = {
     /* 名称, 签名, 函数指针 */
    { "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 }
};
复制代码

经过RegisterMethodsOrDie(),将为gBinderMethods数组中的方法创建了一一映射关系,从而为Java层访问JNI层提供通道

总之,int_register_android_os_Binder方法的主要功能:

  • 经过gBinderOffsets,保存Java层Binder类的信息,为JNI层访问Java层提供通道;
  • 经过RegisterMethodsOrDie,将gBinderMethods数组完成映射关系,从而为Java层访问JNI层提供通道。

注册BinderInternal

android_util_Binder.cpp

static int int_register_android_os_BinderInternal(JNIEnv* env) {
   //其中kBinderInternalPathName = "com/android/internal/os/BinderInternal"
   jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

   gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
   gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");

   return RegisterMethodsOrDie(
       env, kBinderInternalPathName,
       gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
复制代码

注册BinderInternal类的jni方法,gBinderInternalOffsets保存了BinderInternal的forceBinderGc()方法。

static const JNINativeMethod gBinderInternalMethods[] = {
   { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
   { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
   { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
   { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
复制代码

注册BinderProxy

android_util_Binder.cpp

static int int_register_android_os_BinderProxy(JNIEnv* env) {
    //gErrorOffsets保存了Error类信息
    jclass clazz = FindClassOrDie(env, "java/lang/Error");
    gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);

    //gBinderProxyOffsets保存了BinderProxy类的信息
    //其中kBinderProxyPathName = "android/os/BinderProxy"
    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");

    //gClassOffsets保存了Class.getName()方法
    clazz = FindClassOrDie(env, "java/lang/Class");
    gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");

    return RegisterMethodsOrDie(
        env, kBinderProxyPathName,
        gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
复制代码
static const JNINativeMethod gBinderProxyMethods[] = {
     /* 名称, 签名, 函数指针 */
    {"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},
};
复制代码

这部份内容,读者只要清楚这些JNI对应的函数,系统会在运行开始之初帮你作好这些工做就好了

JNI的代码去哪找?

/frameworks/base/core/jni/

找到 android_util_Binder.cpp(JNI的命名通常是 包名路径_对应的JAVA函数名称)

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) {
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}
复制代码

看到了熟悉的东西了没,ProcessState::self()就是前面在cpp代码时分析过的

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    return getStrongProxyForHandle(0);
}
复制代码

它的handle是0,0是什么,是service_manager,因此 ProcessState::self()->getContextObject(NULL) 返回的是一个 new BpBinder(0)

那么接下来再看看 javaObjectForIBinder 是个什么东西

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val) {
    ......
    //使用c代码调用NewObject来建立JAVA BinderProxy对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        //设置该对象的mObject = val.get = b = new BpBinder(0)
        env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
        ......
    }
    return object;
}
复制代码

所以 ServiceManagerNative.asInterface 等价于

ServiceManagerNative.asInterface(new BinderProxy())
其中 BinderProxy的mObject指向new BpBinder(0)

接下来看 asInterface

static public IServiceManager asInterface(IBinder obj) {
     //obj为BpBinder
    if (obj == null) { 
        return null;
    }
    //因为obj为BpBinder,该方法默认返回null
    IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    return new ServiceManagerProxy(obj); 
}
复制代码

所以 ServiceManagerNative.asInterface 等价于

new ServiceManagerProxy(new BinderProxy())

看看ServiceManagerProxy的构造函数

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
}
复制代码

mRemote为 BinderProxy 对象,该BinderProxy对象对应于BpBinder(0)
其做为binder代理端,指向native层的serviceManager

得知,getIServiceManager 就是获取一个 ServiceManagerProxy对象

既然它是一个BpBinder,在咱们写cpp代码的时候,就应该知道它能干什么,注册服务获取服务等等

那么,framework层从 ServieManager的getService 开始,ServiceManagerProxy为本身的mRemote设置 BinderInternal.getContextObject() 从经过JNI方式返回的IBinder(指向service_manager)对象,后续经过 ServiceManagerProxy 来调用服务功能

获取到服务的binder后,下一步就是使用服务了

咱们以前是这么用的

IHelloService svr = IHelloService.Stub.asInterface(binder);

如今去找到aidl生成的文件,找到 asInterface

// 根据 IBinder 构建一个 IHelloService 在android的源码中,这种使用方法很是常见
        public static IHelloService asInterface(android.os.IBinder obj) {
            if ((obj==null)) {
                return null;
            }
            android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
            if (((iin!=null)&&(iin instanceof IHelloService))) {
                return ((IHelloService)iin);
            }
            return new IHelloService.Stub.Proxy(obj);
        }
复制代码

IHelloService.Stub.Proxy 是什么,也是aidl为咱们生成的

//客户端的代理 是一个RPC过程,远程调用服务端的方法
private static class Proxy implements IHelloService{
    private android.os.IBinder mRemote;
    Proxy(android.os.IBinder remote){
        mRemote = remote;
    }
}
复制代码

这样就把Proxy中的mRemote赋值

而后就是调用服务中的方法了,以前咱们的代码是svr.sayhello();

sayhello在Proxy中对应的函数方式代码以下

@Override
            public void sayhello() throws android.os.RemoteException {
                android.os.Parcel _data = android.os.Parcel.obtain();
                android.os.Parcel _reply = android.os.Parcel.obtain();
                try {
                    _data.writeInterfaceToken(DESCRIPTOR);
                    mRemote.transact(Stub.TRANSACTION_sayhello, _data, _reply, 0);
                    _reply.readException();
                } finally {
                    _reply.recycle();
                    _data.recycle();
                }
            }
复制代码

那 mRemote.transact 是调用到哪里去?

mRemote 分析过他是一个 JAVA 中的 BinderProxy 对象(8.0被抽出来了,8.0的源码不少结构上都会有小小的变化,可能由于以前的代码的可读性确实比较差劲吧)

那么找到 BinderProxy 的 transact 函数

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        ......
        try {
            return transactNative(code, data, reply, flags);
        } finally {
            if (tracingEnabled) {
                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
            }
        }
    }
复制代码

最终调用 transactNative ,又是native,那么咱们就去源码里找

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) {
    ...
    //java Parcel转为native Parcel
    Parcel* data = parcelForJavaObject(env, dataObj);
    Parcel* reply = parcelForJavaObject(env, replyObj);
    ...
    
    //在前面的分析过程当中咱们设置了gBinderProxyOffsets.mObject为BpBinder,如今把这个BpBinder(0)取出来
    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    ...

    //这个 target->transact 是 BpBinder::transact(),进入Binder驱动曾
    status_t err = target->transact(code, *data, reply, flags);
    ...
    return JNI_FALSE;
}
复制代码

BpBinder::transact() 是否是很熟悉,cpp部分的源码,忘记的话回头看看cpp部分的分析,简单说下

  • BpBinder::transact()
  • IPCThreadState::self()->transact
  • writeTransactionData
  • waitForResponse
  • talkWithDriver
  • executeCommand

就是开个循环与server端进行通讯,接受server端返回的数据

到此为止,client端就能够发送它的数据,这里是一个RPC远程调用过程,咱们已经解决了第一个问题,client如何发送数据

接下来看第二个问题,Service是如何读取到数据,如何调用到onTransact函数的

回头看看AIDL为咱们生成的代码

case TRANSACTION_sayhello:
                {
                    data.enforceInterface(DESCRIPTOR);
                    this.sayhello();
                    reply.writeNoException();
                    return true;
                }
复制代码

在服务端是调用 this.sayhello()

这个this 是什么

@Override public android.os.IBinder asBinder() {
    return this;
}
复制代码

能够得知他是一个IBinder,那么这个IBinder具体是指什么?

要分析server端的逻辑,就要从头开始了

咱们编写server端的时候并无本身写循环,那么他是怎么处理的?显然啊,确定是系统本身处理了

在哪处理的?实际上是使用app_process来启动server进程的过程当中处理的

对于 AppRuntime 笔者不作过多分析,固然后续会有博文讲解

源码在 /frameworks/base/cmds/app_process/app_main.cpp 中

AppRuntime中有一个 onStarted() 函数

virtual void onStarted() {
    sp<ProcessState> proc = ProcessState::self();
    if (proc->supportsProcesses()) {
        LOGV("App process: starting thread pool.\n");
        proc->startThreadPool();
    }
    AndroidRuntime* ar = AndroidRuntime::getRuntime();
    ar->callMain(mClassName, mClass, mArgC, mArgV);
    if (ProcessState::self()->supportsProcesses()) {
        IPCThreadState::self()->stopProcess();
    }
}
复制代码

注意到 proc->startThreadPool(),从名字应该能看出来,他是启动一个线程池

这个 proc 是一个 ProcessState

ProcessState 是什么还记得吗?

表示进程的一个结构体,在cpp部分作过度析

startThreadPool 总不能也忘了吧,忘了回头看看cpp的内部机制

  • proc->startThreadPool()
  • spawnPooledThread(true)
  • sp<Thread> t = new PoolThread(isMain)
  • t->run(name.string())
  • IPCThreadState::self()->joinThreadPool(mIsMain)

在 joinThreadPool 中就开始循环处理请求了,根据命令处理,若是是 BR_TRANSACTION 就会根据cookie 转换为 BBinder,并调用他的 transact,BBinder的transact其实就等价于他的 onTransact

到此,咱们解决了第二问题的一部分,也就是 server 是如何读取到数据

那么还剩最后一个问题,如何调用到onTransact函数的

既然BBinder的transact等价于他的 onTransact,那咱们看看AIDL生成的文件中,他的 IBinder 实际对象是否为前面分析的 BBinder,若是是,整个流程就全通了

那就要从server端的开头开始分析了

server端流程

看看 addService 函数

public static void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority) {
        try {
            getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
}
复制代码

前面分析知道 getIServiceManager() 获得的是一个 ServiceManagerProxy ,找到他的 addService 函数

public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    data.writeStrongBinder(service);
    data.writeInt(allowIsolated ? 1 : 0);
    // code 是 ADD_SERVICE_TRANSACTION
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
}
复制代码

重点在于 writeStrongBinder

writeStrongBinder

public writeStrongBinder(IBinder val){
    nativewriteStrongBinder(mNativePtr, val);
}
复制代码

又是一个native,去找找他对应的函数,在 android_os_Parcel.cpp 中

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object) {
    //将java层Parcel转换为native层Parcel
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        // .cookie = ibinderForJavaObject(env, object)获得一个JavaBBinder对象
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}
复制代码

看看 ibinderForJavaObject 是什么

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    //注意这个 obj 是传进来的 service 对象
    if (obj == NULL) return NULL;

    //Java层的Binder对象
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL; 
    }
    //把一个Java对象(new XXXService()) 转换为cpp IBinder对象
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }
    return NULL;
}
复制代码

看看 JavaBBinderHolder 的 get,他返回的是一个 JavaBBinder

sp<JavaBBinder> get(JNIEnv* env, jobject obj) {
    AutoMutex _l(mLock);
    sp<JavaBBinder> b = mBinder.promote();
    // 这是一个wp类型的,可能会被垃圾回收器给回收,因此每次使用前,都须要先判断是否存在
    if (b == NULL) {
        b = new JavaBBinder(env, obj);
        mBinder = b;
    }
    return b;
}
复制代码

看下 JavaBBinder 的构造函数

class JavaBBinder : public BBinder
{
    JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }
}
复制代码

他是一个 BBinder,愈来愈接近咱们前面的猜测了

data.writeStrongBinder(service)最终等价于 parcel->writeStrongBinder(new JavaBBinder(env, obj));

obj = new XXXService() ,JavaBBinder的mObject = obj

parcel的writeStrongBinder是什么?

status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}
复制代码

看到 flatten_binder 应该熟悉了,根据IBinder构建 flat_binder_object ,而且把binder对象写道cookie里去,后续server才能经过cookie里去读取并使用

mRemote.transact

回到以前的调用,data.writeStrongBinder(service) 把数据进行一个转换并放入data后

调用

mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)

还记得这个mRmote是什么吗

咱们分析 IServiceManager 的时候

class ServiceManagerProxy implements IServiceManager {
    public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
    }
}
复制代码

mRemote为 BinderProxy 对象,该 BinderProxy 对象对应于BpBinder(0)

那么找到 BinderProxy 的 transact 函数,其实前面已经分析过这部分了

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        ......
        try {
            return transactNative(code, data, reply, flags);
        } finally {
            if (tracingEnabled) {
                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
            }
        }
    }
复制代码

最终调用 transactNative ,又是native,那么咱们就去源码里找

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) {
    ...
    //java Parcel转为native Parcel
    Parcel* data = parcelForJavaObject(env, dataObj);
    Parcel* reply = parcelForJavaObject(env, replyObj);
    ...
    
    //在前面的分析过程当中咱们设置了gBinderProxyOffsets.mObject为BpBinder,如今把这个BpBinder(0)取出来
    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
    ...

    //这个 target->transact 是 BpBinder::transact(),进入Binder驱动曾
    status_t err = target->transact(code, *data, reply, flags);
    ...
    return JNI_FALSE;
}
复制代码

BpBinder::transact() cpp部分的源码

  • BpBinder::transact()
  • IPCThreadState::self()->transact
  • writeTransactionData
  • waitForResponse
  • talkWithDriver
  • executeCommand

开个循环与server端进行通讯,接受server端返回的数据,这里咱们的client端是server,server端是service_manager

总结注册服务流程

  • new XXXService()
  • data.writeStrongBinder(service)
  • JNI调用
  • service JAVA对象 转换为 JAVABBinder cpp对象
  • 将 JAVABBinder 给 cookie
  • 调用 BinderProxy 的 transact
  • BpBinder::transact()
  • 与驱动进行通讯
  • 驱动接收数据,完成服务的注册工做

到此为止,咱们只是分析了他如何注册服务的,还没获得咱们第三个问题的答案

以前分析过,系统会帮咱们建立一个循环来担任server端的循环处理工做,那么在循环过程当中,会去读取客户端发送过来的消息,在分析cpp的代码时,会在接收到数据后,取出 cookie 转换为 BBinder,并调用BBinder派生类的onTransact函数,咱们注册服务的时候,BBinder的派生类是 JAVABBinder ,所以咱们只须要去找 JAVABBinder 的 onTransact 函数

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 int strict_policy_before = thread_state->getStrictModePolicy();
        thread_state->setLastTransactionBinderFlags(flags);
        //调用JAVA中的某个函数
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, (int32_t)&data, (int32_t)reply, flags);
        jthrowable excep = env->ExceptionOccurred();
        ......
        return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
    }
复制代码

看 CallBooleanMethod 它到底调用的是JAVA里的哪一个函数

jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
复制代码

mObject指向 XXXService对象
gBinderOffsets.mExecTransact指向: android/os/Binder类中的 execTransact 方法
那么上面的 CallBooleanMethod 就是调用XXXService(派生自Binder)对象中的execTransact方法

那么查找 execTransact,它是在AIDL为咱们生成的文件中,Stub的父类,Binder里面

private boolean execTransact(int code, long dataObj, long replyObj, int flags) {
        BinderCallsStats binderCallsStats = BinderCallsStats.getInstance();
        BinderCallsStats.CallSession callSession = binderCallsStats.callStarted(this, code);
        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);
            }
            res = onTransact(code, data, reply, flags);
        } catch (RemoteException|RuntimeException e) {
            ......
        } finally {
            ......
        }
        ......
        return res;
    }
复制代码

能够发现,它调用的是 onTransact 函数,这个onTransact就是它的子类实现的 onTransact,它的子类就是AIDL为咱们生成的 Stub 中,在咱们以前写的测试代码中是这样的

@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_sayhello:
                {
                    data.enforceInterface(DESCRIPTOR);
                    this.sayhello();
                    reply.writeNoException();
                    return true;
                }
                case TRANSACTION_sayhello_to:
                {
                    data.enforceInterface(DESCRIPTOR);
                    java.lang.String _arg0;
                    _arg0 = data.readString();
                    int _result = this.sayhello_to(_arg0);
                    reply.writeNoException();
                    reply.writeInt(_result);
                    return true;
                }
            }
            return super.onTransact(code, data, reply, flags);
        }
复制代码

至此,咱们已经知道第三个问题的答案了,知道它是如何调用到JAVA层的onTransact函数

笔者完善了开头的图

相关文章
相关标签/搜索