天天看點

Android Binder java端的調用流程

本篇從ServiceManager.addService中開始講起

Android Binder getService(java)源碼分析(二)_we1less的部落格-CSDN部落格關于native層在java端的代理ServiceManagerProxy對象已經在這篇闡述過了

addService

        路徑  frameworks/base/core/java/android/os/ServiceManagerNative.java

        data.writeStrongBinder(service);

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);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }
           

writeStrongBinder

        路徑  frameworks/base/core/java/android/os/Parcel.java

        java層的Parcel 主要是調用native層的Parcel

public final void writeStrongBinder(IBinder val) {
        nativeWriteStrongBinder(mNativePtr, val);
    }
           

 nativeWriteStrongBinder

        路徑  frameworks/base/core/jni/android_os_Parcel.cpp

        native層的Parcel的writeStrongBinder入參要是sp<IBinder>& val

        jobject object類型轉換主要靠ibinderForJavaObject

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    if (parcel != NULL) {
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}
           

ibinderForJavaObject

        路徑  frameworks/base/core/jni/android_util_Binder.cpp

        将java層的對象轉換為Ibinder類型        

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;
    //判斷傳遞進來的對象是否是gBinderOffsets.mClass的子類
    //可以看出gBinderOffsets.mClass是java的Binder類
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            //從obj中擷取gBinderOffsets.mObject成員屬性并強轉成JavaBBinderHolder類型
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }

    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}
           
const char* const kBinderPathName = "android/os/Binder";

static int int_register_android_os_Binder(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderPathName);

    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    //...
}
           

gBinderOffsets.mObject 

        路徑  frameworks/base/core/jni/android_util_Binder.cpp

       gBinderOffsets.mObject是何時被指派成JavaBBinderHolder?

        當init的時候直接new出來被設定進去的  同樣的這個方法也是一個jni方法

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

{ "init", "()V", (void*)android_os_Binder_init },
           

 init

        路徑  frameworks/base/core/java/android/os/Binder.java

        很顯然是當初始化java層子類service的構造器的時候初始化的

public Binder() {
        init();
        ...
    }
           

jbh->get(env, obj)

        路徑  frameworks/base/core/jni/android_util_Binder.cpp

        直接傳回new的一個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;
    }
           

 JavaBBinder

        路徑   frameworks/base/core/jni/android_util_Binder.cpp

        将傳遞進來的對象指派給mObject

JavaBBinder(JNIEnv* env, jobject object)
        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
    {
        ALOGV("Creating JavaBBinder %p\n", this);
        android_atomic_inc(&gNumLocalRefs);
        incRefsCreated(env);
    }
           

         這樣就可以用傳遞進來的mObject對象回調java層的onTransact方法

        調用mObject的gBinderOffsets.mExecTransact方法 就是調用Binder.java的execTransact

virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
        ...
        jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
           

execTransact

        路徑  frameworks/base/core/java/android/os/Binder.java 

        因為mObject對象是繼承Binder對象是以調用的是父類Binder對象的execTransact方法

        最後調用到自身的onTransact方法

private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
        ...
            res = onTransact(code, data, reply, flags);