android 系统核心机制binder(11)binder java层 TestServer分析

112 篇文章 88 订阅

该系列文章总纲链接:专题分纲目录 android 系统核心机制 binder


本章关键点总结 & 说明:

这里关注➕ Binder Java实现中的TestServer分析,这里主要关注 服务添加添加流程。

Java层TestServer解析,首先看服务端代码:

import android.util.Slog;
import android.os.ServiceManager;

public class TestServer {
    private static final String TAG = "TestServer";

    public static void main(String args[])
    {
        //关键点:注册服务
        ServiceManager.addService("hello", new HelloService());

        while (true)
        {
            try {
            	Thread.sleep(100);
          	} catch (Exception e){}
        }
    }
}

这里 只有一个 关键点,就是注册服务,因此server端的流程就是服务注册流程,接下来逐层解析。

根据 前面对binder java层的理解,一定是先创建ServiceManagerProxy,在此基础上继续分析addService流程。

addService代码如下所示:

public static void addService(String name, IBinder service) {
        try {
            getIServiceManager().addService(name, service, false);
        } catch (RemoteException e) {
            Log.e(TAG, "error in addService", e);
        }
    }

1.1 getIServiceManager函数分析

getIServiceManager代码实现如下:

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

        //调用asInterface,传递的参数类型为IBinder    
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

 asInterface的参数为BinderInternal.getContextObject的返回值。详细分析BinderInternal.getContextObject。这是一个native的函数,代码声明如下:

public static final native IBinder getContextObject();

查看native方法的注册,如下所示:

static const JNINativeMethod gBinderInternalMethods[] = {
     /* name, signature, funcPtr */
    { "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 }
};

这里getContextObject对应C++的方法android_os_BinderInternal_getContextObject,代码实现如下所示:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    //下面这句代码,它将返回一个BpProxy对象,其中NULL(即0,用于标识目的端)指定Proxy通信的目的端是ServiceManager
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b); //由Native对象创建一个Java对象,下面分析该函数
}

这里详细分析javaObjectForIBinder,代码实现如下所示:

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

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

    AutoMutex _l(mProxyLock); //mProxyLock是一个全局的静态CMutex对象

    // val对象实际类型是BpBinder,读者可自行分析BpBinder.cpp中的findObject函数。
    // 事实上,在Native层的BpBinder中有一个ObjectManager,它用来管理在Native BpBinder
    // 上创建的Java BpBinder对象。下面这个findObject用来判断gBinderProxyOffsets
    // 是否已经保存在ObjectManager中。如果是,那就需要删除这个旧的object
    jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
    if (object != NULL) {//如果objetc存在,那就需要删除这个object
        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);
    }

    //创建一个新的BinderProxy对象,并注册到Native BpBinder对象的ObjectManager中
    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);

        jobject refObject = env->NewGlobalRef(env->GetObjectField(object, gBinderProxyOffsets.mSelf));
        //将这个新创建的BinderProxy对象注册(attach)到BpBinder的ObjectManager中
        //同时注册一个回收函数proxy_cleanup。当BinderProxy对象撤销(detach)的时候,
        //该函数会被调用,以释放一些资源。自行研究proxy_cleanup函数。
        val->attachObject(&gBinderProxyOffsets, refObject,jnienv_to_javavm(env), proxy_cleanup);

        //DeathRecipientList保存了一个用于死亡通知的list
        sp<DeathRecipientList> drl = new DeathRecipientList;
        drl->incStrong((void*)javaObjectForIBinder);

        //将死亡通知list和BinderProxy对象联系起来
        env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
        android_atomic_inc(&gNumProxyRefs);//增加该Proxy对象的引用计数

        //下面这个函数用于垃圾回收。创建的Proxy对象一旦超过200个,该函数将调用BinderInternal类的ForceGc做一次垃圾回收
        incRefsCreated(env);
    }

    return object;
}

BinderInternal.getContextObject函数主要完成了以下2个工作:

  1. 创建了一个Java层的BinderProxy对象。
  2. 通过JNI,该BinderProxy对象和一个Native的BpProxy对象挂钩,而该BpProxy对象的通信目标就是ServiceManager。

1.2 分析asInterface函数
在Native层Binder中有个著名的interface_cast宏。在Java层中虽没有这样的宏,但是定义了一个类似的函数asInterface。下面来分析ServiceManagerNative类的asInterface函数,其代码如下:

static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }
        IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }
        
        return new ServiceManagerProxy(obj); //以obj为参数,创建一个ServiceManagerProxy对象
    }

上面代码和Native层interface_cast非常类似,都是以一个BpProxy对象为参数构造和业务相关的ServiceManagerProxy。 它的各个业务函数会将相应请求打包后交给BpProxy对象,最终由BpProxy对象发送给Binder驱动以完成一次通信。
注意:实际上BpProxy也不会和Binder驱动交互,真正和Binder驱动交互的是IPCThreadState。
到此,getIServiceManager()分析完毕,即得到了一个ServiceManagerProxy(BinderProxy(0));
2 addService函数分析

现在来分析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);  //注意下面这个writeStrongBinder函数,后面我们会详细分析它
        data.writeInt(allowIsolated ? 1 : 0);
        //mRemote实际上就是BinderProxy对象,调用它的transact,将封装好的请求数据发送出去
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

找到native方法的注册,如下所示:

static const JNINativeMethod gBinderProxyMethods[] = {
     /* name, signature, funcPtr */
    {"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},
};

BinderProxy的transact是一个native函数,其对应的native实现函数android_os_BinderProxy_transact的代码如下所示:

static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,

        jint code, jobject dataObj, jobject replyObj, jint flags)
{
    //...
    Parcel* data = parcelForJavaObject(env, dataObj); //从Java的Parcel对象中得到Native的Parcel对象
    //...
    Parcel* reply = parcelForJavaObject(env, replyObj); //得到一个用于接收回复的Parcel对象
    //...
    //通过Native的BpBinder对象,将请求发送给ServiceManager
    status_t err = target->transact(code, *data, reply, flags);
    //...
    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/);
    return JNI_FALSE;
}

看了上面的代码会发现,Java层的Binder最终还是要借助Native的Binder进行通信的。接下来就是Binder Native层的通信模型了,即BpBinder(0)、也就是最后依然使用IPCThreadState的 trsansact函数向service_manager发送请求注册,添加服务。Java层在这里做的更多是封装。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

图王大胜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值