在了解完binder在native层以及驱动层的基本流程之后(参考Android如何注册服务到ServiceManager; Android 系统服务管家servicemanager启动过程详解 ),接下来这篇文章我们就来分析下binder在framework层(Java层)的具体原理与实现,重点围绕Java层如何添加服务到系统中这一主题展开。这里会谈到以下几个方面的问题:

  • binder在Java层的具体架构与实现
  • binder在Java层的ServiceManager又是如何实现
  • Android中如何加载注册binder相关的JNI方法

binder源码涉及面广,错误之处难以避免,欢迎各位批评指正

binder在Java层的具体实现

下图为Android框架层ServiceManager的结构简图。可以看到,框架层的ServiceManager主要是为上层应用或服务提供一个统一的接口,用于向系统注册、查询或者获取服务,在另一端Binder以及BinderProxy则通过JNI方法调用native层的方法,以此来使用binder底层提供的接口。

  • ServiceManager是一个不可初始化的类,其向外提供了addService(添加服务)、getService(获取服务)、checkService(检查服务)、listService列举所有系统服务等接口,并返回系统服务相关的IBinder接口;
  • IServiceManager是一个接口,ServiceManager正是通过该接口的实现ServiceManagerProxy来调用native层的代码的;
  • ServiceManagerProxy代理对象有一个mRemote变量,该变量实际是一个BinderProxy实例,通过BinderProxy就可以将Java层的RPC请求发送给native层,进而传递给binder驱动;
  • IBinder是RPC调用的一个抽象接口,代表了一个远程对象,通过该接口,我们可以向服务端发送RPC请求,该接口的核心函数是transact:
    public boolean transact(int code, Parcel data, Parcel reply, int flags)        throws RemoteException;

这是一个同步调用,只有当服务端返回时,该函数才会返回结果。

源码(以下分析均基于Android N7.0): /android/frameworks/base/core/java/android/os/ServiceManager.java

接下来,就来看看上层如何调用ServiceManager接口将系统服务注册到系统中的?

注册服务到servicemanager

在系统服务进程SystemServer启动后,会注册很多服务,包括系统核心服务以及其他非系统服务:

    private void run() {        ....        // 启动服务        try {            //启动自举服务:PowerManager,DisplayManger 等等            startBootstrapServices();            //启动系统核心服务            startCoreServices();            //启动其他服务:Vibrator,TelecomRegistry,NetworkConnectivity...            startOtherServices();        } catch (Throwable ex) {            throw ex;        } finally {            Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);        }        ....    }    private void startOtherServices() {        ....        telephonyRegistry = new TelephonyRegistry(context);        ServiceManager.addService("telephony.registry", telephonyRegistry);        ....        vibrator = new VibratorService(context);        ServiceManager.addService("vibrator", vibrator);        ....    }

代码路径:/android/frameworks/base/services/java/com/android/server/SystemServer.java

调用ServiceManager方法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);        }    }    private static IServiceManager sServiceManager;    // 获取IServiceManager接口    private static IServiceManager getIServiceManager() {        if (sServiceManager != null) {            return sServiceManager;        }        // 获取servicemanager        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());        return sServiceManager;    }

这里,BinderInternal.getContextObject()究竟返回的是什么了?进去一看,发现getContextObject()是一个本地化方法,需要通过JNI来调用native的代码:

    // 一个本地化方法    public static final native IBinder getContextObject();

直接搜索 getContextObject,发现在android_util_Binder.cpp这个JNI文件中,定义了相应的JNI函数:

    static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)    {        // 获取serviemanager对应的binder对象: BpBinder(0)        sp b = ProcessState::self()->getContextObject(NULL);        // 这里返回的是什么了?        return javaObjectForIBinder(env, b);    }    jobject javaObjectForIBinder(JNIEnv* env, const sp& val)    {        ....        // 新建一个BinderProxy对象?        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->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;    }    // 保存了BinderProxy类的信息    static struct binderproxy_offsets_t    {        // Class state.        jclass mClass;        jmethodID mConstructor;        jmethodID mSendDeathNotice;        // Object state.        jfieldID mObject;        jfieldID mSelf;        jfieldID mOrgue;    } gBinderProxyOffsets;

从这里,我们大概可以判断出,javaObjectForIBinder实际返回的是一个Java对象BinderProxy,该对象有一个成员变量mObject保存了一个本地的BpBinder引用(参考Android如何注册服务到ServiceManager)。那么,与BinderProxy紧密相关的结构体变量gBinderProxyOffsets又是在何时被初始化的,这个疑问留到下一节“binder JNI方法的初始化”再来分析。暂时,我们知道BinderInternal.getContextObject()返回的是一个servicemanager对应的BinderProxy。这样

    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());

就等价于: sServiceManager = ServiceManagerNative.asInterface(new BinderProxy());,接着看一看asInterface这个方法:

    /**     * Cast a Binder object into a service manager interface, generating     * a proxy if needed.     */    static public IServiceManager asInterface(IBinder obj)    {        if (obj == null) {            return null;        }        // BinderProxy直接返回null        IServiceManager in =            (IServiceManager)obj.queryLocalInterface(descriptor);        if (in != null) {            return in;        }        // 新建一个ServiceManagerProxy(BindProxy)对象        return new ServiceManagerProxy(obj);    }    // ServiceManagerProxy构造函数,将BinderProxy实例保存到mRemote中    public ServiceManagerProxy(IBinder remote) {        mRemote = remote;    }

源码: /android/frameworks/base/core/java/android/os/ServiceManagerNative.java

到这里,不难看出,调用ServiceManager.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);        data.writeInt(allowIsolated ? 1 : 0);        // 调用BinderProxy的transact,发送RPC请求到servicemanager        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);        reply.recycle();        data.recycle();    }    // BinderProxy    final class BinderProxy implements IBinder {        public IInterface queryLocalInterface(String descriptor) {            return null;        }        ....        public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {            Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");            ....            return transactNative(code, data, reply, flags);        }        //调用JNI方法发送RPC请求        public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;    }

那么,transactNative又是如何调用到native层的方法的了?同样在android_util_Binder.cpp中定义了BinderProxy相关的JNI方法,其中transactNative对应的JNI方法是android_os_BinderProxy_transact

    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},    };    static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,            jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException    {        if (dataObj == NULL) {            jniThrowNullPointerException(env, NULL);            return JNI_FALSE;        }        // gBinderProxyOffsets.mObject 就是指向servicemanger的远程对BpBinder(0)        IBinder* target = (IBinder*)            env->GetLongField(obj, gBinderProxyOffsets.mObject);        if (target == NULL) {            jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");            return JNI_FALSE;        }        ....        // BpBinder->transact(...)        status_t err = target->transact(code, *data, reply, flags);        ....    }

到这了BpBinder以后,就与之前的一篇文章Android如何注册服务到ServiceManager所讲的流程完全一样了。

binder JNI方法的初始化

在上文中提到,BinderInternal.getContextObject()返回的是一个BinderProxy对象,同时该对象会引用一个native层的BpBinder实例。那么,Android究竟是如何初始化JNI?又是如何根据gBinderProxyOffsets这个结构体变量来构造一个Java对象BinderProxy的了?

在Android启动过程中(参考Android开机流程,init进程通过init.zygotexxx.rc来启动zygote系统服务用于加载虚拟机实例(系统只有一个zygote进程,但是不同进程会有不同的VM实例,不同的VM实例会通过zygote来共享一些共有的数据):

    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server        class main        socket zygote stream 660 root system        onrestart write /sys/android_power/request_state wake        onrestart write /sys/power/state on        onrestart restart audioserver        onrestart restart cameraserver        onrestart restart media        onrestart restart netd

找到app_process进程的代码入口:

    int main(int argc, char* const argv[])    {        //获取runtime实例        AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));        // ignore argv[0]        argc--;        argv++;        bool zygote = false;        bool startSystemServer = false;        ++i;  // Skip unused "parent dir" argument.        while (i < argc) {            const char* arg = argv[i++];            if (strcmp(arg, "--zygote") == 0) {                zygote = true;                niceName = ZYGOTE_NICE_NAME;            } else if (strcmp(arg, "--start-system-server") == 0) {                startSystemServer = true;                }            }             if (startSystemServer) {                args.add(String8("start-system-server"));            }            ....        }        ....        // 创建第一个Dalvik VM实例,启动ZygoteInit进程        if (zygote) {            runtime.start("com.android.internal.os.ZygoteInit", args, zygote);        } else if (className) {            runtime.start("com.android.internal.os.RuntimeInit", args, zygote);        }        ....    }

源码: /android/frameworks/base/cmds/app_process/app_main.cpp

    void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)    {        ....        //初始化VM参数,创建VM实例        JniInvocation jni_invocation;        jni_invocation.Init(NULL);        JNIEnv* env;        if (startVm(&mJavaVM, &env, zygote) != 0) {            return;        }        onVmCreated(env);        // 注册JNI函数        if (startReg(env) < 0) {            ALOGE("Unable to register all android natives\n");            return;        }        ....        //启动zygote进程:新建一个SystemServer进程,加载系统基础类与库        char* slashClassName = toSlashClassName(className);        jclass startClass = env->FindClass(slashClassName);        if (startClass == NULL) {            ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);            /* keep going */        } else {            jmethodID startMeth = env->GetStaticMethodID(startClass, "main",                "([Ljava/lang/String;)V");            if (startMeth == NULL) {                ALOGE("JavaVM unable to find main() in '%s'\n", className);            } else {                //调用ZygoteInit的main函数                env->CallStaticVoidMethod(startClass, startMeth, strArray);            ....        }        ....    }

系统JNI方法都是在函数startReg(env)中注册上的:

    /*static*/ int AndroidRuntime::startReg(JNIEnv* env)    {        ....        env->PushLocalFrame(200);        //注册所有的JNI函数到系统中        if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {            env->PopLocalFrame(NULL);            return -1;        }        env->PopLocalFrame(NULL);        return 0;    }    //gRegJni是系统JNI函数指针结构体数组    #define REG_JNI(name)      { name }    struct RegJNIRec {        int (*mProc)(JNIEnv*);    };    static const RegJNIRec gRegJNI[] = {        ....        REG_JNI(register_android_os_Process),        REG_JNI(register_android_os_SystemProperties),        //注册binder相关的JNI函数        REG_JNI(register_android_os_Binder),        REG_JNI(register_android_os_Parcel),        REG_JNI(register_android_nio_utils),        ....    };

找到register_android_os_Binder函数所在源码:android_util_Binder.cpp,在这个函数里,会注册所有和Binder框架层相关的JNI函数:

    int register_android_os_Binder(JNIEnv* env)    {        //注册Binder.java对应的JNI        if (int_register_android_os_Binder(env) < 0)            return -1;        //注册BinderInternal.java对应的JNI        if (int_register_android_os_BinderInternal(env) < 0)            return -1;        //注册BinderProxy.java对应的JNI        if (int_register_android_os_BinderProxy(env) < 0)            return -1;        ....        return 0;    }

正是在int_register_android_os_BinderProxy这个函数里,初始化了结构体变量gBinderProxyOffsets,其中mClass指向一个全局的BinderProxy引用,mConstructor指向BinderProxy的构造函数,而mObject初始化为BinderProxy的成员变量的ID值。这样初始化后,我们就可以使用gBinderProxyOffsets直接返回一个BinderProxy实例了。

    const char* const kBinderProxyPathName = "android/os/BinderProxy";    static int int_register_android_os_BinderProxy(JNIEnv* env)    {        //查找BinderProxy类        clazz = FindClassOrDie(env, kBinderProxyPathName);        gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);        gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "", "()V");        gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",                "(Landroid/os/IBinder$DeathRecipient;)V");        gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");        ....        //注册BinderProxy相关的JNI        return RegisterMethodsOrDie(            env, kBinderProxyPathName,            gBinderProxyMethods, NELEM(gBinderProxyMethods));    }

至此,我们对Binder框架层也有了一个比较深入的理解与认识。这里,对如何在框架层添加系统服务的流程做一个简单的总结:

  1. 调用ServiceManageraddService()接口时,getIServiceManager返回一个ServiceManagerProxy对象;
  2. 调用ServiceManagerProxyaddService()接口;
  3. ServiceManagerProxy中有一个mRomote成员变量指向一个BinderProxy对象,它是本地servicemanager的远程代理;
  4. 通过JNI接口transactNative()发送数据到libbinder;

更多相关文章

  1. Android与JS之间的互相调用交互(一)
  2. 硬件访问服务4之Android硬件访问服务框架及系统函数全详细实现
  3. android的binder机制研究(C++部分)
  4. 如何调用Android隐藏API
  5. 实现自己的Camera
  6. Android应用程序注冊广播接收器(registerReceiver)的过程分析
  7. android JNI层线程回调Java函数
  8. Android(安卓)Activity类应用技巧分享
  9. 箭头函数的基础使用

随机推荐

  1. android基本的五大布局(3)
  2. Android(安卓)深入解析AsyncTask(doInBack
  3. Android多媒体分析(六)对AudioManager的一
  4. android WebView html网页设置长按的时候
  5. android内核读取file文件
  6. 获取 Andorid 手机WIFI连接的Mac地址和IP
  7. android设置定时关闭的dialog
  8. [转]Android(安卓)获取当前Activity的屏
  9. Android标题栏渐变色,沉寂式状态栏
  10. Android(安卓)studio 设计简易的计算器