binder机制原理分析(四):java层service的注册过程

binder机制原理分析一共分5个部分,其实省了一点,但是分析到后面都差不多了,以后再补充吧。

1、ServiceManager 进程启动

2、普通Service注册到ServiceManager

3、从ServiceManager中获取服务

4、java层service的注册过程

5、Java层service的获取过程

步骤一、初始化注册jni对象

Binder通信最终还是依赖与native层,java层的binder是native层binder的一个封装,实现还是在native层,这个映射关系在系统初始化的时候(在AndroidRuntime.cpp中)就将javaBinder和nativeBinder进行建立。并分别有结构体与之对应,如gBinderOffset与Binder、gBinderInternalOffset与BinderInternal、gBinderProxyOffset与BinderProxy的映射关系,映射的地址都存在对应结构起的mObject中。

首先初始化jni:为了通过java调用native

int register_android_os_Binder(JNIEnv* env){
建立native与javaBinder之间的映射关系,gBinderOffset与Binder的映射,地址都存在mObject中
    if (int_register_android_os_Binder(env) < 0)
        return -1;
建立native与javaBinderInternal之间的映射关系,gBinderInternalOffset与BinderInternal的映射
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
建立native与javaBinderProxy之间的映射关系,gBinderProxyOffset与BinderProxy的映射
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;
    return 0;
}

举例:AMS的启动过程

ActivityManagerService.java
public void setSystemProcess() {
        ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
}
ServiceManager.java
public static void addService(String name, IBinder service) {
	 getIServiceManager().addService(name, service, false);
}

步骤二、首先获取ServiceManager对象

private static IServiceManager getIServiceManager() {
..............判空略过.............
    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
    return sServiceManager;
}
BinderInternal.getContextObject()中调用的是native IBinder getContextObject(),因此:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz){
    //好熟悉的味道~~~
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    BpBinder(0)
    return javaObjectForIBinder(env, b);
}

如果是native的addService,那么到这里就结束了,java层还需要转换一下:

  1. new BinderProx(),它是Binder的内部类
  2. BinderProx.mObject = BpBinder(0),也就是吧BpBinder(0)给了BinderProxy的mObject对象
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val){
    .........
     //创建一个新的BinderProxy对象,并将它注册到Natice BpBinder对象的ObjectManager中
    object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
    if (object != NULL) {
        // 通过BinderProxy.mObject,把这个BpBinder对象和BinderProxy对象关联了起来
        env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
        val->incStrong((void*)javaObjectForIBinder);
        jobject refObject = env->NewGlobalRef(
                env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        val->attachObject(&gBinderProxyOffsets, refObject,
                jnienv_to_javavm(env), proxy_cleanup);
        // 新建一个死亡通知,并将死亡通知list存放在binder代理的mOrgue里面
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);
      env->SetLongField(object,gBinderProxyOffsets.mOrgue,reinterpret_cast<jlong>(drl.get()));
        android_atomic_inc(&gNumProxyRefs);
        incRefsCreated(env);
    }
    return object;
}
所以前面的getIServiceManager就变成了ServiceManagerNative.asInterface(new BinderProxy());
private static IServiceManager getIServiceManager() {
..............判空略过.............
    sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());
    return sServiceManager;
}
ServiceManagerNative & ServiceManagerNative.class
这里接着asInterface方法,为了进一步获取java层代理类
static public IServiceManager asInterface(IBinder obj){
    //BinderProxy.class中的queryLocalInterface()方法很干脆,直接返回null。
    IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
    if (in != null) {
        return in;
    }
    //所以最终得到一个jave层binder的代理类ServiceManagerProxy()
    return new ServiceManagerProxy(obj);
}
public IInterface queryLocalInterface(String descriptor) {
    return null;
}

小节一下:

因此addService方法最后返回的IServiceManager就是new ServiceManagerProxy(new BinderProxy()),这个跟C++中得到的new BpServiceManager(new BpBinder(0))其实是一毛一样的,都是熟悉的味道。而且BinderProxy中的mObject对象其实就是存着native层的new BpBinder(0)。

步骤三、addService

封装parcel对象

获取到ServiceManager后就可以addService了,实际调用的是ServiceManagerProxy的addService方法

public void addService(String name, IBinder service, boolean allowIsolated)throws RemoteException{
同样,先封装一个parcel对象,java层的parcel也是对native层parcel的一个封装,
java层存的是native层parcel的地址对象。
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
这里跟native的方法一样,也是通过native的Parcel::的writeStrongBinder方法写入server
    data.writeStrongBinder(service); 
    data.writeInt(allowIsolated ? 1 : 0);native中也是通过remote()——>transact方法将信息透传到IPCThreadState中去发送,这里的remote就是java层的BinderProxy对象。一个套路
    mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
    reply.recycle();
    data.recycle();
}

调用transact方法

BinderProxy中的transact调用了transactNative方法,也就是下面这个,将数据抛到了native层处理

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,jint code, jobject dataObj, jobject replyObj, jint flags){
    ........这里一大坨是将java式的参数转为native式..........
    然后就是从BinderProxy的mObject中将BpBinder(0)对象取出来。
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
然后就是这句熟悉的话
    status_t err = target->transact(code, *data, reply, flags);
}
最后在来说说这句:因为这个service是new出来的,而且service都继承了Binder对象。因此也调用了Binder的构造方法Binder(){init()},这个init()方法调用的就是native的init方法。
static void android_os_Binder_init(JNIEnv* env, jobject obj){
这里创建了JavaBBinderHolder,然后将它跟BinderOffset的mObject绑定。Jbh—>get一下就是JavaBBinder
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    jbh->incStrong((void*)android_os_Binder_init);
    env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}

Parcel中的writeStrongBinder方法

public final void writeStrongBinder(IBinder val) {
    nativeWriteStrongBinder(mNativePtr, val);
}
这里nativePtr就是Parcel.cpp的地址,ibinderForJavaObject(env, object)就是调用了object.get
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object){
    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
    const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
}
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj){
如果是Binder类型,就获取JavaBBinder对象
    if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
        JavaBBinderHolder* jbh = (JavaBBinderHolder*)
            env->GetLongField(obj, gBinderOffsets.mObject);
        return jbh != NULL ? jbh->get(env, obj) : NULL;
    }
如果是BinderProxy对象就获取BpBinder对象
    if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
        return (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
    }
    return NULL;
}

这里也就是相当于:
const status_t err = parcel->writeStrongBinder(new JavaBBinder());
最后设置AMS的type类型,远程的BINDER_TYPE_HANDLER、本地的BINDER_TYPE_BINDER
status_t flatten_binder(const sp<ProcessState>&const sp<IBinder>& binder, Parcel* out){
 	IBinder *local = binder->localBinder();
        if (!local) {
            BpBinder *proxy = binder->remoteBinder();
            const int32_t handle = proxy ? proxy->handle() : 0;
            obj.type = BINDER_TYPE_HANDLE;
        } else {
            obj.type = BINDER_TYPE_BINDER;
        }
    return finish_flatten_binder(binder, obj, out);
}

接下来的过程就跟native注册server是binder的传输是一样的了。通过IpcThreadState调用transact方法,执行与binder驱动的一些列交互。

总结:

java层的binder注册最终还是通过调用native方法完成的,getIServiceManager()先获取到ServiceManagerProxy(BinderProxy),其中BinderProxy相当于BpBinder,ServiceManagerProxy相当于IServiceManager,然后通过BinderProxy.trance()方法通过调用transactNative()将parcel发送到native层去。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值