Android Framework实战开发-binder通信java及jni部分源码分析

107 篇文章 12 订阅
23 篇文章 1 订阅

csdn在线学习课程,课程咨询答疑和新课信息:QQ交流群:422901085进行课程讨论

android跨进程通信实战视频课程(加群获取优惠)

1、第一部分进程与ServiceManager通信及客户端程序发起调用详解

平时大部分获取ServiceManager中的某一个服务,一般都是最后都是ServiceManager.getService这种方式:

//ServiceManager.java中
    public static IBinder getService(String name) {
        try {
            IBinder service = sCache.get(name);
            if (service != null) {
                return service;
            } else {
                return Binder.allowBlocking(getIServiceManager().getService(name));
            }
        } catch (RemoteException e) {
            Log.e(TAG, "error in getService", e);
        }
        return null;
    }

这里getIServiceManager()如下:

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

        // Find the service manager
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

这里最后也是调用了BinderInternal.getContextObject(),这里getContextObject是个native方法,所以继续追到了native层:
这个对应native方法在:
frameworks\base\core\jni\android_util_Binder.cpp中

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

大家看他又调用到了 ProcessState::self()->getContextObject,获取了native层面的IBinder对象,然后再调用javaObjectForIBinder把这个对象进行转换成java对象
先来看 ProcessState::self()->getContextObject方法:

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

这里其实是调用getStrongProxyForHandle(0),记住哦这里传递handle的参数是0,因为ServiceManager的一个应用固定就是0,他是我们跨进程通信一切一切的基础,几乎所有跨进程通信都是需要通过它

sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                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;
}

这刚开始handle_entry肯定为null,所以这里其实就是new BpBinder(0)对象进行返回,那么这里大家就应该清楚,最后进程获取ServiceManager对应的IBinder对象,其实本质就是BpBinder对象,这个对象由对应的handle值,通过这个handle值传递到了驱动,驱动就可以知道与哪个进程进行通信,0当然是ServiceManager进程。
到这里我们就获取的一个BpBinder,但是这个是也是native层面的,怎么把它变成java层面的对象呢?这里就需要来看javaObjectForIBinder(env, b)方法:

jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
   //。。省略
	//这里构造出了gBinderProxyOffsets的java对象
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        // The proxy holds a reference to the native object.
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());//这里吧val这个c++的对象指针设置到gBinderProxyOffsets.mObject这个java属性中
        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建立对应的java对象,及java对象可以直接拿到val指针,但是我们进程也需要val指针可以获取到java对象,这个就是,来关联
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);

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

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

    return object;
}

其中的gBinderProxyOffsets修改看如下:

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);
    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");
。。省略
}

其实本质都是通过jni方式来构造
好了那么回到最初始:
ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
这个里面allowBlocking可以暂时忽略,名字它只是个和阻塞不阻塞相关,BinderInternal.getContextObject()本身就已经是BinderProxy类型对象了,所以asInterface其实就是:
new ServiceManagerProxy(obj);这里obj其实就是ServiceManagerProxy类中的mRemote,通信时候其实都是调用这个mRemote的transact方法

那接下来获取了ServiceManager已经分析的很清楚了,那么看看他的一个getSevice方法,这里其实addService肯定也是完全类似的,就只需要分析一个既可以:
那么我们来看getIServiceManager().getService(name)方法:

    public IBinder getService(String name) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
        IBinder binder = reply.readStrongBinder();
        reply.recycle();
        data.recycle();
        return binder;
    }

这里看看出,它首先要进行跨进程通信就要准备好数据包Parcel,data代表要传递过去的,reply代表要传递回来的,然后再调用最关键的mRemote.transact,这里前面分析过了mRemote本质是BinderProxy类型,故来看BinderProxy的transact(注意BinderProxy类在Binder.java这个文件中):

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 对应的jni 方法在:

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
   。。省略

    IBinder* target = (IBinder*)
        env->GetLongField(obj, gBinderProxyOffsets.mObject);
   
  。。省略

    //printf("Transact from Java code to %p sending: ", target); data->print();
    status_t err = target->transact(code, *data, reply, flags);
  。。省略
}

这里其实就是获取BinderProxy中的mObject对象,因为他存储是c++层面的BpBinder对象地址,故target其实就是调用BpBinder的transact:

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) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

这里看看到最后又调用到了IPCThreadState的transact方法

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
   。。省略
    if (err == NO_ERROR) {
        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;
}

writeTransactionData主要目的就是把数据组装成驱动的binder_transaction_data结构体
然后又会根据是否为oneway区分,但是最后都是调用waitForResponse方法:

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
    uint32_t cmd;
    int32_t err;

    while (1) {
        if ((err=talkWithDriver()) < NO_ERROR) break;
        if (mIn.dataAvail() == 0) continue;

        cmd = (uint32_t)mIn.readInt32();
        switch (cmd) {
        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                if (err != NO_ERROR) goto finish;

                if (reply) {
                    if ((tr.flags & TF_STATUS_CODE) == 0) {
                        reply->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);
                    } else {
                   。。省略
                    }
                }
。。省略
}

这里循环调用talkWithDriver,然后获取结果。驱动部分我们下一节会讲解,这里我们到这里就知道,binder通信在自己进程最后都会调用到talkWithDriver来与binder驱动进行通信。
这里就直接给出返回结果为对应的Serivce的handle,然后利用这个handle构造出对应的BpBinder即这一部分就完全和IServiceManager的获取是一样的,只不过ServiceManager是直接new BpBinder(0)
而远程服务则是需要先从ServiceManager中获取handle,然后再new BpBinder(handle)
至此为止,我们就分析清楚了客户端发起一个跨进程调用的java到jni的所有流程

2、服务进程的方法被调用流程从上到下详解

服务端的方法被调用流程相比客户端的主动发起调用流程更加难分析,这里我们可以分成2个部分来进行分析:
在这里插入图片描述

2.1 native层的BBinder执行分析:

因为这里只涉及到native层面,相对不用把java部分搞一起,相对分析起来会简单,讲解完了这一部分在去讲解java端怎么运行相对就会简单很多,如果一起讲解相对理解难度会非常大。
我们前面应该知道,native层面进行跨进程通信时候,服务端主要负责实现一个BBinder类,它最主要的方法就是onTransact方法:

 virtual status_t onTransact(uint32_t code, const Parcel& data,
                              Parcel* reply, uint32_t flags = 0) {
    ALOGD( "Service onTransact, code = %d" , code);
    switch (code) {
    case FUNC_CALLFUNCTION:
      callFunction();
      break;
    default:
      return BBinder::onTransact(code, data, reply, flags);
    }
    return 0;
  }

这里其实就是已经进入了我们的服务端的方法具体方法实现了,那么到底是怎么一步步到这里呢?
这里当然大家可以采用以前我们说过的用类似java的打印调用堆栈方法来追踪。这里我们后面再给大家展示既可以,本节课就暂时不讲啦。
那首先来看看到 IPCThreadState::self()->joinThreadPool( true);这个方法就代表会一直不断来读取驱动发过来数据

  do {
  。。省略

        result = getAndExecuteCommand();
。。省略
        }
    } while (result != -ECONNREFUSED && result != -EBADF);

其实他就是在不断执行getAndExecuteCommand

status_t IPCThreadState::getAndExecuteCommand()
{
    。。省略
    result = talkWithDriver();
    if (result >= NO_ERROR) {
        size_t IN = mIn.dataAvail();
        if (IN < sizeof(int32_t)) return result;
        cmd = mIn.readInt32();
      。。省略
        result = executeCommand(cmd);
	  。。省略
    }

    return result;
}

这里是不是talkWithDriver会与驱动进行通信获取了对应result和数据写入了mIn中,读取cmd,然后调用了executeCommand(cmd)方法

status_t IPCThreadState::executeCommand(int32_t cmd)
{
。。省略
    switch ((uint32_t)cmd) {
    case BR_TRANSACTION:
        {
            binder_transaction_data tr;
            result = mIn.read(&tr, sizeof(tr));
            
            if (tr.target.ptr) {
                if (reinterpret_cast<RefBase::weakref_type*>(
                        tr.target.ptr)->attemptIncStrong(this)) {
                    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);
            }
            if ((tr.flags & TF_ONE_WAY) == 0) {
                sendReply(reply, 0);
            }
。。省略

        }
        break;
。。省略
    return result;
}

这里省略的大部分,我们主要关心case BR_TRANSACTION:情况
有这句关键代码:
error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
这里是不是大概可以看出一个BBinder指针调用对应的transact方法,好像我们发现了真相是吧?都看到transact了,那么继续看看transact方法,因为我们自己没有实现过这个transact,只是重写了onTransact(注意哦,这里的BBinder类在Binder.cpp中):

status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
      ..省略
    switch (code) {
          ..省略
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }
    ..省略
    return err;
}

这里是不是就看到了我们的onTransact,这里就是真正调用到我们自己写的服务的onTransact方法中。

那这里好像就讲完了粗略流程。但是还有许多细节哦,比如
reinterpret_cast<BBinder*>(tr.cookie)->transact()
这里面的tr.cookie我们猜想肯定是我们自己的SampleService这个继承BBinder对象的类。但是它是到底怎么一步步变成了这里的tr.cookie 我们并不清楚,那么我们就来详细分析一下:
那么首先得回到最开始ServiceManager的addService:

 virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

这里是不是把自己的service通过Parcel 的writeStrongBinder写入了,那来看看writeStrongBinder:

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

接下来看看flatten_binder:

status_t flatten_binder(const sp<ProcessState>& /*proc*/,
    const sp<IBinder>& binder, Parcel* out)
{
    flat_binder_object obj;
。。省略
    if (binder != NULL) {
        IBinder *local = binder->localBinder();
        if (!local) {
            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 {
            obj.type = BINDER_TYPE_BINDER;
            obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
            obj.cookie = reinterpret_cast<uintptr_t>(local);
        }
    }
。。省略
    return finish_flatten_binder(binder, obj, out);
}

这里我们可以看到binder->localBinder();它是用来判断是不是本地binder对象:

BBinder* BBinder::localBinder()
{
    return this;
}

明显这里就返回了自己,所以返回是SampleService,那就是进入以下:

  	obj.type = BINDER_TYPE_BINDER;
	obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
	obj.cookie = reinterpret_cast<uintptr_t>(local);

这里大家是不是看到了一个cookie 东西,它赋值为了local也就是我们的SampleService这个BBinder类对象

2.2 java端的Binder执行与到native层映射分析

2.1 已经清楚binder驱动是怎么调用到native的BBinder的,但同学们肯定又会问,我们平时写的代码都是java层面,请问java层又是怎么个流程呢?这个其实java当然也是基于native层面的BBinder来实现的,具体我们来看代码:
假设是调用java层的ServiceManager来addService

    ServiceManager.addService("MyService", new MyService());//注册服务
//其中的MyService是真正的实现服务端的实现类,这里是不是看出和native层BBinder的要素是不是基本一致,
//最主要是onTransact这个实现,其实这里是由native层面调用过来的,稍后解密
public class MyService extends Binder implements IMyService{

  public MyService() {
    this.attachInterface(this, DESCRIPTOR);
  }

  @Override
  public IBinder asBinder() {
    return this;
  }

  /** 将MyService转换为IMyService接口 **/
  public static com.test.frameworkBinder.IMyService asInterface(android.os.IBinder obj) {
   。。省略
  }

  /**  服务端,接收远程消息,处理onTransact方法  **/
  @Override
  protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
    throws RemoteException {
    switch (code) {
    。。省略
    case TRANSACTION_say: {
      data.enforceInterface(DESCRIPTOR);
      String str = data.readString();
      sayHello(str);
      reply.writeNoException();
      return true;
    }
    }
    return super.onTransact(code, data, reply, flags);
  }

  /** 自定义sayHello()方法   **/
  @Override
  public void sayHello(String str) {
    System.out.println("MyService:: Hello, " + str);
  }


}

那么首先我们来看ServiceManager.addService干了啥:
在ServiceManagerNative.java

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

这里调用的是data.writeStrongBinder(service);来把我们service写入:
在Parcel.java

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

调用是nativeWriteStrongBinder,是个native方法
base\core\jni\android_os_Parcel.cpp

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

其实他也是调用的native的Parcel类的writeStrongBinder方法,这个方法上一节讲过,但是这里大家看参数是一个java层面的object,所以调用了ibinderForJavaObject(env, object)方法来进行转换,这个方法也就是java层面到native可以打通的一个核心:

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
    if (obj == NULL) return NULL;

    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (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);
    }
    return NULL;
}

这里我们业务是本地实现的Binder对象,所以不是gBinderProxyOffsets.mClass,是我们的gBinderOffsets.mClass,这里看看这个gBinderOffsets.mClass:

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

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

这方法里面对gBinderOffsets相关的方法和属性进行了设置,大家可以看到mClass 类名其实是android/os/Binder,而我们的MyService本身就是继承android.os.Binder对象,同时注意这里还对execTransact和mObject进行了声明

在回到ibinderForJavaObject:

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

这里会发现从MyService中的mObject对象获取了native层面的JavaBBinderHolder(有个疑问为啥可以获取,java层mObject什么时候变成了JavaBBinderHolder指针,这个稍后解答),然后再调用了JavaBBinderHolder的get方法,就可以获取一个native层面的BBinder对象:

class JavaBBinderHolder : public RefBase
{
public:
    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;
        }
        return b;
    }

    sp<JavaBBinder> getExisting()
    {
        AutoMutex _l(mLock);
        return mBinder.promote();
    }

private:
    Mutex           mLock;
    wp<JavaBBinder> mBinder;
};

这里可以看到get方法确实会在方法里面构造一个JavaBBinder返回,而且大家注意哦,这里是不是还把java层的jobject传递给了JavaBBinder,目前其实就是为了后续JavaBBinder肯定先收到驱动的调用,但是这里JavaBBinder他也要调用到Java层面。

class JavaBBinder : public BBinder
{
public:
    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);
    }

    bool    checkSubclass(const void* subclassID) const
    {
        return subclassID == &gBinderOffsets;
    }

    jobject object() const
    {
        return mObject;
    }

protected:
。。省略

    virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {。。省略
        JNIEnv* env = javavm_to_jnienv(mVM);
	
        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;
    }
。。省略
private:
    JavaVM* const   mVM;
    jobject const   mObject;
};

到这里JavaBBinder 即它本身也是BBinder相信大家就已经明白,上节课native时候就已经分析过了,最后binder的读取线程会调用到onTransact这个方法,我们看这里是不是有一个CallBooleanMethod方法来调用到java端,这里是调用了gBinderOffsets.mExecTransact方法,它对于是java层Binder的execTransact方法:

  // Entry point from android_util_Binder.cpp's onTransact
    private boolean execTransact(int code, long dataObj, long replyObj,
            int flags) {
     。。省略
        try {
           。。省略
            res = onTransact(code, data, reply, flags);
        } catch (RemoteException|RuntimeException e) {
           。。省略
        } finally {
           。。省略
        }
      。。省略
        return res;
    }

大家看这里他就会调用onTransact,这个onTransact方法当然就调用到了子类MyService的onTransact,故是不是整个java层面到native层面的穿透是不通了
最后解答一下,JavaBBinderHolder什么时候放到了java层mObject,这里我们肯定就来搜索new JavaBBinderHolder的地方:

static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    。。省略
    jbh->incStrong((void*)android_os_Binder_init);
    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}

这里大家可以看出是在android_os_Binder_init方法,它把JavaBBinderHolder对象指针赋值给了mObject,这个方法一看就是jni的一个方法,:

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

名字其实可以知道是Binder.java的init方法,而且init是native的
果然Binder.java定义声明如下:
private native final void init();
这里看看init是在哪里被调用的:

 public Binder() {
        init();
。。省略
    }

他是在Binder()默认构造方法中执行,回到开始MyService 是不是继承Binder:
class MyService extends Binder
所以子类构造会先执行父类构造
4、总结类图
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值