Binder系列之:Parcel之writeStrongBinder到readStrongBinder

背景:Parcel.cpp是Android提供的一个容器类,通过binder传输的数据都可以写进Parcel中。但是因为Parcel中的数据最终都会copy到驱动空间,而驱动空间为每一个进程分配的内存是限的,如果Parcel中的数据量太大就会造成数据传输失败。所以,binder通信中不适宜用Parcel传输诸如图片这样的数据,如果有需求传输大容量数据,可以使用共享内存IMemory,Parcel中不仅可以装载int,float,string这样的基础数据类型,还可以装载IBinder对象,文件句柄等特殊对象。我们先来看看JavaParcel是如何装载IBinder对象

以下代码是Parcel.java 中的片段

public final class Parcel {
  
//JNI层Parcel.cpp 对象句柄引用
private long mNativePtr; 
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_create 方法
private static native long nativeCreate();
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_readStrongBinder 方法
private static native IBinder nativeReadStrongBinder(long nativePtr);
//对应在JNI层android_os_Parcel.cpp 文件中android_os_Parcel_writeStrongBinder 方法
private static native void nativeWriteStrongBinder(long nativePtr, IBinder val);
private Parcel(long nativePtr) {
      if (DEBUG_RECYCLE) {
            mStack = new RuntimeException();
        }
        //Log.i(TAG, "Initializing obj=0x" + Integer.toHexString(obj), mStack);
        init(nativePtr);
    }  

//内部提供一个获取Parcel对象方法
    public static Parcel obtain() {
        final Parcel[] pool = sOwnedPool;
//先看看池子里面有没有
        synchronized (pool) {
            Parcel p;
            for (int i=0; i

流程1.在创建Java层Parcel对象时,首先在构造函数内初始化mNativePtr ,通过JNI层android_os_Parcel.cpp 文件中android_os_Parcel_create 方法将JNI层的Parcel(.cpp)对象句柄赋值给mNativePtr ;看下android_os_Parcel_create方法

static jlong android_os_Parcel_create(JNIEnv* env, jclass clazz)
{
    Parcel* parcel = new Parcel();
    return reinterpret_cast(parcel);
}

流程2.nativeWriteStrongBinder 方法对应JNI层的android_os_Parcel.cpp文件中android_os_Parcel_writeStrongBinder()方法:

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
//将Java层持有的句柄转成JNI层的Parcel对象
    Parcel* parcel = reinterpret_cast(nativePtr);
    if (parcel != NULL) {
//object 是Java层的IBinder对象
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

流程3.ibinderForJavaObject方法是什么鬼,有什么用,不急,先源码贴上该方法在android_util_Binder.cpp文件中:

sp ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    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层BinderProxy类实例
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }

    ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
    return NULL;
}

先判断下Java层传过来的IBinder对象是Binder实例还是BinderProxy实例,gBinderOffsets.mClass代表Java层的Binder类?不信,往下瞧。
流程3.1.gBinderOffsets.mClass是在android_util_Binder.cpp 中赋值的

const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
//获取Java层Binder类
    jclass clazz = FindClassOrDie(env, kBinderPathName);
//全局引用
    gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//将Java层的Binder中execTransact方法句柄赋值给  gBinderOffsets.mExecTransact 
    gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//将Java层的Binder 中mObject字段句柄赋值给  gBinderOffsets.mObject 
    gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

    return RegisterMethodsOrDie(
        env, kBinderPathName,
        gBinderMethods, NELEM(gBinderMethods));
}

int_register_android_os_Binder 方法主要是将Java层Binder类中申明的native 方法与JNI层的关联起来,在虚拟机启动时int_register_android_os_Binder 会被注册进去,大家注意到这句代码没有

  gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

Binder 中mObject 这个字段是什么?在哪里赋值?在这里我们先做个记号,后面会分析道
流程3.2.gBinderProxyOffsets.mClass 在int_register_android_os_BinderProxy方法中赋值:

const char* const kBinderProxyPathName = "android/os/BinderProxy";
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);
//将Java层的BinderProxy 类赋值给 gBinderProxyOffsets.mClass 
    gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "", "()V");
    gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
            "(Landroid/os/IBinder$DeathRecipient;)V");
//将Java层的BinderProxy 中的mObjcet 字段赋值给 gBinderProxyOffsets.mObject
    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));
}

int_register_android_os_BinderProxy方法主要是将Java层BinderProxy类中申明的native 方法与JNI层的关联起来,在虚拟机启动时int_register_android_os_BinderProxy 会被注册进去,大家注意到这句代码没有

  gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");

BinderProxy中mObject 这个字段是什么,在哪里赋值?在这里我们先做个记号,后面会分析道
流程3.3.回到ibinderForJavaObject方法,先分析下如果是Binder实例

 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;

先不分析,再看下jbh->get(env, obj) 返回的是什么,源码奉上

class JavaBBinderHolder : public RefBase
{
public:
    sp get(JNIEnv* env, jobject obj)
    {
        AutoMutex _l(mLock);
        //将mBinder 提升为强指针
        sp 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 getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }

private:
    Mutex           mLock;
    wp mBinder;
};

返回的是JavaBBinder,先通过Java层的Binder类中mObject 字段值转换成JavaBBinderHolder 指针,再由该指针get 到JavaBBinder,
流程3.4还记得我们在流程3.1抛出的问题吗?mObject 是什么在哪里赋值,解铃还须系铃人,先看看Java层的Binder类有什么东西吧
Binder.java


public class Binder implements IBinder {
...
//这个分析的主角,该值是在JNI层赋值的
    private long mObject;
    private IInterface mOwner;
    private String mDescriptor;
    private native final void init();
    private native final void destroy();
    public Binder() {
        init();
        if (FIND_POTENTIAL_LEAKS) {
            final Class klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }
    }
}

先从构造函数下手吧,init方法是个native,好吧去android_util_Binder.cpp 中的android_util_Binder_init方法看看吧

//JNIEnv类型实际上代表了Java环境,通过这个JNIEnv* 指针,就可以对Java端的代码进行操作。例如,创建Java类中的对象,调用Java对象的方法,获取Java对象中的属性等等。JNIEnv的指针会被JNI传入到本地方法的实现函数中来对Java端的代码进行操作。
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);
    //参数:jobject obj的解释:

//如果native方法不是static的话,这个obj就代表这个native方法的类实例

//如果native方法是static的话,这个obj就代表这个native方法的类的class对象实例(static方法不需要类实例的,所以就代表这个类的class对象)
    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);//将JavaBBinderHolder 指针赋值给JAVA 层的Binder.java 中的mObject字段
}

是不是很激动,请看

 env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);

流程3.1可知,gBinderOffsets.mObject 持有Java层Binder字段mObject的句柄,因此,该代码实际上是将 JavaBBinderHolder 类型指针赋值给Java层Binder字段mObject,在看下这句代码

 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;

现在豁然开朗了吧。
顺便,我们来分析下流程3.2抛出的BinderProxy中mObject 这个字段是什么,在哪里赋值,驾轻就熟,先看Java层的BinderProxy类,其实他是在Binder.java 文件中

final class BinderProxy implements IBinder {
.....
 public native boolean transactNative(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;
    public native void linkToDeath(DeathRecipient recipient, int flags)
            throws RemoteException;
    public native boolean unlinkToDeath(DeathRecipient recipient, int flags);
.....

}

你会发现并没有mObject字段,其实他用的外部类Binder 中的mObject字段,但是我们在android_util_Binder.cpp文件中并没有找到类似初始化赋值,(其实是有赋值的)I have dream,如果是BinderProxy实例流程则执行

(IBinder*)
  env->GetLongField(obj, gBinderProxyOffsets.mObject);

很明显,不做解释;
流程4回到流程2,由流程3可知,ibinderForJavaObject返回的是JavaBBinder 继承 BBinder (本流程暂时默认ibinderForJavaObject方法中的流程是走if中的流程),回顾下流程2的代码

static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
//将Java层持有的句柄转成JNI层的Parcel对象
    Parcel* parcel = reinterpret_cast(nativePtr);
    if (parcel != NULL) {
//object 是Java层的IBinder对象,如果object 是Binder对象,则下面代码可以等效
// const status_t err = parcel->writeStrongBinder(JavaBBinder );
        const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
        if (err != NO_ERROR) {
            signalExceptionForError(env, clazz, err);
        }
    }
}

跟着代码来到Parcel.cpp中的writeStrongBinder方法

status_t Parcel::writeStrongBinder(const sp& val)
{
    return flatten_binder(ProcessState::self(), val, this);
}

流程5.继续看ProcessState::self()

sp ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    gProcess = new ProcessState("/dev/binder");
    return gProcess;
}

看看ProcessState构造函数

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))//打开Binder驱动
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
            mDriverName.clear();
        }
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

这两个函数本次先不详细分析,简单来说就是打开Binder驱动,在映射一块内存地址,将该地址首地址返回,再看看flatten_binder方法

status_t flatten_binder(const sp& /*proc*/,
    const sp& binder, Parcel* out)
{
//Parcel中存放的binder对象,以此数据结构来表征
    flat_binder_object obj;

    if (IPCThreadState::self()->backgroundSchedulingDisabled()) {
        /* minimum priority for all nodes is nice 0 */
//所有节点的最低优先级都是0
        obj.flags = FLAT_BINDER_FLAG_ACCEPTS_FDS;
    } else {
        /* minimum priority for all nodes is MAX_NICE(19) */
//所有节点的最低优先级最大19
        obj.flags = 0x13 | FLAT_BINDER_FLAG_ACCEPTS_FDS;
    }
    if (binder != NULL) {
//如果binder是BinderProxy对象,此处为null
        IBinder *local = binder->localBinder();
        if (!local) {
//如果binder为BBinder及其子类实例对象此处返回null
            BpBinder *proxy = binder->remoteBinder();
            if (proxy == NULL) {
                ALOGE("null proxy");
            }
            const int32_t handle = proxy ? proxy->handle() : 0;
//标明是个代理
            obj.type = BINDER_TYPE_HANDLE;
            obj.binder = 0; /* Don't pass uninitialized stack data to a remote process */
            obj.handle = handle;
            obj.cookie = 0;
        } else {
//标明是个BBinder
            obj.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast(local->getWeakRefs());
            obj.cookie = reinterpret_cast(local);
        }
    } else {
        obj.type = BINDER_TYPE_BINDER;
        obj.binder = 0;
        obj.cookie = 0;
    }

    return finish_flatten_binder(binder, obj, out);
}

流程6.本函数其实就是对flat_binder_object 结构数据赋值,那我们先来看看该结构体吧

/*
 * This is the flattened representation of a Binder object for transfer
 * between processes.  The 'offsets' supplied as part of a binder transaction
 * contains offsets into the data where these structures occur.  The Binder
 * driver takes care of re-writing the structure type and data as it moves
 * between processes.
 */
struct flat_binder_object {
    struct binder_object_header hdr;
    __u32               flags;

    /* 8 bytes of data. */
    union {
        binder_uintptr_t    binder; /* local object */
        __u32           handle; /* remote object */
    };

    /* extra data associated with local object */
    binder_uintptr_t    cookie;
};

看此结构体的注释,大概知道了,其实也最终解密了writeStrongBinder 的目的,就是将BBinder或者BpBinder 对象转换成flat_binder_object 结构体,最终flat_binder_object 会通过Parcel.cpp 的writeObject 方法,写入到mData,mObject中,看看Parcel.cpp 的writeObject

status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
{
    const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
    const bool enoughObjects = mObjectsSize < mObjectsCapacity;
    if (enoughData && enoughObjects) {
restart_write:
 // 如果空间足够,他把前面组装的flat_binder_object实体追加到mData里
        *reinterpret_cast(mData+mDataPos) = val;

        // remember if it's a file descriptor
        if (val.type == BINDER_TYPE_FD) {
            if (!mAllowFds) {
                // fail before modifying our object index
                return FDS_NOT_ALLOWED;
            }
            mHasFds = mFdsKnown = true;
        }

        // Need to write meta-data?
        if (nullMetaData || val.binder != 0) {
// mObjects记录每次向mData追加的flat_binder_object的偏移位置
            mObjects[mObjectsSize] = mDataPos;
            acquire_object(ProcessState::self(), val, this, &mOpenAshmemSize);
            mObjectsSize++;
        }

        return finishWrite(sizeof(flat_binder_object));
    }

    if (!enoughData) {
//空间不够,申请空间
        const status_t err = growData(sizeof(val));
        if (err != NO_ERROR) return err;
    }
    if (!enoughObjects) {
//超出数组长度,扩容
        size_t newSize = ((mObjectsSize+2)*3)/2;
        if (newSize*sizeof(binder_size_t) < mObjectsSize) return NO_MEMORY;   // overflow
        binder_size_t* objects = (binder_size_t*)realloc(mObjects, newSize*sizeof(binder_size_t));
        if (objects == NULL) return NO_MEMORY;
        mObjects = objects;
        mObjectsCapacity = newSize;
    }

    goto restart_write;
}

通过以上流程,我们分析了一个Binder对象由Java层的Parcel 再由JNI层的android_os_Parcel.cpp转换成BBinder,最终写入了JNI层Parcel.cpp的mData 中,那么这个mData怎么被送去驱动层的呢?在Parcel.cpp中有个mOut,有什么用,是不是mData就是通过mData out出去,我们先放一放,后面会有专门一章节分析,我们先看看readStrongBinder 这个方法,由于有了分析writeStrongBinder 的经验,后面的流程我可能会简化一些
流程7Parcel.java 中readStrongBinder 方法的native实现是在android_os_Parcel.cpp 中的android_os_Parcel_readStrongBinder 方法
android_os_Parcel.cpp

static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
    Parcel* parcel = reinterpret_cast(nativePtr);
    if (parcel != NULL) {
        return javaObjectForIBinder(env, parcel->readStrongBinder());
    }
    return NULL;
}

nativePtr 的意义与流程1中分析的一样,可以参看流程1,javaObjectForIBinder这个方法似乎有点熟悉,还记得ibinderForJavaObject方法么,其实二者有异曲同工之妙,我们先看看parcel->readStrongBinder(),在Parcel.cpp文件中

sp Parcel::readStrongBinder() const
{
    sp val;
    // Note that a lot of code in Android reads binders by hand with this
    // method, and that code has historically been ok with getting nullptr
    // back (while ignoring error codes).
    readNullableStrongBinder(&val);
    return val;
}
status_t Parcel::readNullableStrongBinder(sp* val) const
{
    return unflatten_binder(ProcessState::self(), *this, val);
}

流程7.1还记得之前分析的flatten_binder吗,看到unflatten_binder是不是很熟悉的感觉,
Parcel.cpp

status_t unflatten_binder(const sp& proc,
    const Parcel& in, sp* out)
{
    const flat_binder_object* flat = in.readObject(false);

    if (flat) {
        switch (flat->type) {
            case BINDER_TYPE_BINDER:
                *out = reinterpret_cast(flat->cookie);
                return finish_unflatten_binder(NULL, *flat, in);
            case BINDER_TYPE_HANDLE:
                *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast(out->get()), *flat, in);
        }
    }
    return BAD_TYPE;
}

这里又出现了flat_binder_object这个结构体,在写的时候也需要先将BBinder转换成该结构体,读的时候也需要先转换成该结构体,再看看readObject函数吧

const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
    const size_t DPOS = mDataPos;
    if ((DPOS+sizeof(flat_binder_object)) <= mDataSize) {
        const flat_binder_object* obj
                = reinterpret_cast(mData+DPOS);
        mDataPos = DPOS + sizeof(flat_binder_object);
        if (!nullMetaData && (obj->cookie == 0 && obj->binder == 0)) {
            // When transferring a NULL object, we don't write it into
            // the object list, so we don't want to check for it when
            // reading.
            ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
            return obj;
        }

        // Ensure that this object is valid...
        binder_size_t* const OBJS = mObjects;
        const size_t N = mObjectsSize;
        size_t opos = mNextObjectHint;

        if (N > 0) {
            ALOGV("Parcel %p looking for obj at %zu, hint=%zu",
                 this, DPOS, opos);

            // Start at the current hint position, looking for an object at
            // the current data position.
            if (opos < N) {
                while (opos < (N-1) && OBJS[opos] < DPOS) {
                    opos++;
                }
            } else {
                opos = N-1;
            }
            if (OBJS[opos] == DPOS) {
                // Found it!
                ALOGV("Parcel %p found obj %zu at index %zu with forward search",
                     this, DPOS, opos);
                mNextObjectHint = opos+1;
                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                return obj;
            }

            // Look backwards for it...
            while (opos > 0 && OBJS[opos] > DPOS) {
                opos--;
            }
            if (OBJS[opos] == DPOS) {
                // Found it!
                ALOGV("Parcel %p found obj %zu at index %zu with backward search",
                     this, DPOS, opos);
                mNextObjectHint = opos+1;
                ALOGV("readObject Setting data pos of %p to %zu", this, mDataPos);
                return obj;
            }
        }
        ALOGW("Attempt to read object from Parcel %p at offset %zu that is not in the object list",
             this, DPOS);
    }
    return NULL;
}

对比下流程6中的writeObject,简直就是一个逆向操作,回到流程7,此时flat的值应该是BINDER_TYPE_HANDLE,为什么是这个值呢,这个是要去Binder驱动层分析才知道,本次先不分析,接着看代码

  *out = proc->getStrongProxyForHandle(flat->handle);
                return finish_unflatten_binder(
                    static_cast(out->get()), *flat, in);

getStrongProxyForHandle这个是不是很熟悉,走进去瞧瞧
ProcessState.cpp

sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  See comment
        // in getWeakProxyForHandle() for more info about this.
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                // Special case for context manager...
                // The context manager is the only object for which we create
                // a BpBinder proxy without already holding a reference.
                // Perform a dummy transaction to ensure the context manager
                // is registered before we create the first local reference
                // to it (which will occur when creating the BpBinder).
                // If a local reference is created for the BpBinder when the
                // context manager is not present, the driver will fail to
                // provide a reference to the context manager, but the
                // driver API does not return status.
                //
                // Note that this is not race-free if the context manager
                // dies while this code runs.
                //
                // TODO: add a driver API to wait for context manager, or
                // stop special casing handle 0 for context manager and add
                // a driver API to get a handle to the context manager with
                // proper reference counting.

                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }

            b = new BpBinder(handle); 
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

返回一个BpBinder,回到流程7javaObjectForIBinder(env, parcel->readStrongBinder()); 等效于javaObjectForIBinder(env,new BpBinder(handler)),在看看javaObjectForIBinder方法

jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {
        // One of our own!
        jobject object = static_cast(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    // For the rest of the function we will hold this lock, to serialize
    // looking/creation/destruction of Java proxies for native Binder proxies.
    AutoMutex _l(mProxyLock);

    // Someone else's...  do we know about it?
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) {
        jobject res = jniGetReferent(env, object);
        if (res != NULL) {
            ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
            return res;
        }
        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
        android_atomic_dec(&gNumProxyRefs);
        val->detachObject(&gBinderProxyOffsets);
        env->DeleteGlobalRef(object);
    }

    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
        // The proxy holds a reference to the native object.
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);

        // The native object needs to hold a weak reference back to the
        // proxy, so we can retrieve the same proxy if it is still active.
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

        // Also remember the death recipients registered on this proxy
        sp drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast(drl.get()));

        // Note that a new object reference has been created.
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }

    return object;
}

还记得gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor在哪里初始化的吗,参看流程3.2,javaObjectForIBinder方法最终返回的是Java层的BinderProxy对象。
总结从Java层的角度来看,我们向内核写入的是Binder对象,最终返回的是BinderProxy对象,其中各个变化在以上流程中都简单分析了下,后面章节我会针对以上流程做更加详细的分析,毕竟我们现在还很多事没有弄清楚,比如流程7.1中的我们留下的一个问题,1.flag的值为什么是BINDER_TYPE_HANDLE呢,这个要求驱动代码中去分析;2:内核到底对我们写入的Binder如何管理的;3.为什么Binder比其他的跨进程通讯要快;4.内存共享是最快的,那Android为什么还要以Binder机制作为基础通讯;

参考:https://www.jianshu.com/p/59a3ca77f71d
参考:http://www.mamicode.com/info-detail-1586374.html
参考:https://mr-cao.gitbooks.io/android/content/android-binder.html

你可能感兴趣的:(Binder系列之:Parcel之writeStrongBinder到readStrongBinder)