美文网首页
Binder机制

Binder机制

作者: 星云春风 | 来源:发表于2019-08-16 07:21 被阅读0次

基本介绍

从IPC角度来说
  • Binder是Android中一种跨进程通信方式,在linux中没有,是Android独有的
从Android Driver层
  • Binder还可以理解为一种虚拟的物理设备,设备驱动是/dev/binder
  • 驱动层位于linux内核中,它提供了最底层的数据传递,对象标识,线程管理,调用过程控制等功能,是整个binder的核心
从Android Native层
  • Binder是创建Service Manager和BpBinder/BBinder模型,搭建与Binder驱动的桥梁
从Android Framework 层
  • Binder是各种Manager(ActivityManager、WindowManager等)和对应的xxxManagerService的桥梁
从Android APP层
  • Binder是服务端和客户端通信的媒介,当binderService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端可以获取到服务端的服务或者数据,这里的服务包含普通的服务和基于AIDL的服务

基本流程

Binder.c中
  • binder_init() 设备初始化
  • binder_open() 打开驱动设备
  • binder_mmap() 先在内核虚拟地址空间,申请一块与用户虚拟内存相同大小的内存,然后再申请一个page大小的物理内存,再将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,从而实现了用户空间的buffer和内核空间的buffer同步操作的功能
    -binder_ioctl() 数据操作
ServiceManager
  • 启动
    • binder_open() 打开biner驱动
    • binder_become_context_manager注册成功binder服务的管家
    • binder_loop()进入无限循环,处理client端发来的请求
  • 获取
  • 通过defaultServiceManager()获取gDefaultServiceManager对象
  • defaultServiceManager 中
    ProcessState::self() ProcessState对象(单例模式),每个进程有且只有一个ProcessState对象
    getContextObject 用于创建BpBinder对象,对于handle=0的BpBinder对象,存在直接返回,不存在直接创建
    interface_cast<IServiceManager>() 用于获取BpServiceManager对象
  • do_add_service()注册
  • svc_can_register() 检查权限,检查selinux权限是否满足
  • find_svc() 服务服务检索,根据服务名来查询匹配的服务
  • svcinfo_death() 释放服务,当查询到已存在的同名服务,则先清理该服务信息,再将当前的服务加入到服务列表svclist中
  • do_find_service()查询服务
  • find_svc()从服务列表中,根据服务名遍历查找是否已经注册,存在则返回服务名,否则返回null
AndroidRuntime.cpp中startReg会注册Binder
int AndroidRuntime::startReg(JNIEnv* env)
{
    ATRACE_NAME("RegisterAndroidNatives");
    /*
     * This hook causes all future threads created in this process to be
     * attached to the JavaVM.  (This needs to go away in favor of JNI
     * Attach calls.)
     */
    androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);

    ALOGV("--- registering native functions ---\n");

    /*
     * Every "register" function calls one or more things that return
     * a local reference (e.g. FindClass).  Because we haven't really
     * started the VM yet, they're all getting stored in the base frame
     * and never released.  Use Push/Pop to manage the storage.
     */
    env->PushLocalFrame(200);

    if (register_jni_procs(gRegJNI, NELEM(gRegJNI), env) < 0) {
        env->PopLocalFrame(NULL);
        return -1;
    }
    env->PopLocalFrame(NULL);

    //createJavaThread("fubar", quickTest, (void*) "hello");

    return 0;
}
android_util_Binder.cpp中
int register_android_os_Binder(JNIEnv* env)
{    //初始化Binder
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
    if (int_register_android_os_BinderProxy(env) < 0)
        return -1;

    jclass clazz = FindClassOrDie(env, "android/util/Log");
    gLogOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gLogOffsets.mLogE = GetStaticMethodIDOrDie(env, clazz, "e",
            "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Throwable;)I");

            
    clazz = FindClassOrDie(env, "android/os/ParcelFileDescriptor");
    gParcelFileDescriptorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gParcelFileDescriptorOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>",
                                                                 "(Ljava/io /FileDescriptor;)V");

    clazz = FindClassOrDie(env, "android/os/StrictMode");
    gStrictModeCallbackOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gStrictModeCallbackOffsets.mCallback = GetStaticMethodIDOrDie(env, clazz,
            "onBinderStrictModePolicyChange", "(I)V");

    return 0;
}
//注册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));
}
//注册Binderinternal
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
    jclass clazz = FindClassOrDie(env, kBinderInternalPathName);

    gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");

    return RegisterMethodsOrDie(
        env, kBinderInternalPathName,
        gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
//注册Binder代理
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");
    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));
}
在ServiceManager中有一个getService(String name)方法获取IBinder对象
 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;
    }
最终会调用ServiceManagerNative中的getService(String 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;
    }
Binder客户端代码
Binder服务端代码

相关文章

网友评论

      本文标题:Binder机制

      本文链接:https://www.haomeiwen.com/subject/vpjwjctx.html