(O)ServiceManager分析(一)之BinderInternal.getContextObject

本文详细探讨了Android中Binder机制的内部实现,从JNI函数注册开始,逐步剖析BinderInternal的getContextObject函数。通过分析,揭示了Binder、BinderInternal和BinderProxy在C++和Java层之间的交互过程,特别是如何创建并返回BinderProxy对象的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. Binder, JNI函数的注册

在分析BinderInternal的getContextObject函数之前,我们有必要先看一下Binder中JNI函数的注册情况

android_os_Binder.cpp

int register_android_os_Binder(JNIEnv* env)
{
	// Leo, 注册Binder的相关JNI函数
    if (int_register_android_os_Binder(env) < 0)
        return -1;
    // Leo, 注册Binderinternal的相关JNI函数
    if (int_register_android_os_BinderInternal(env) < 0)
        return -1;
    // Leo, 注册BinderProxy的相关JNI函数
    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;
}
至于为什么会开始走到这个方法,我们在此不讨论

这个方法,主要是,调用了各个register方法,注册了一些JNI函数,那么具体怎么注册的,我们进入方法中查看,先看int_register_android_os_Binder

static const JNINativeMethod gBinderMethods[] = {
     /* name, signature, funcPtr */
    { "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
    { "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
    { "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
    { "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
    { "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
    { "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
    { "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
    { "init", "()V", (void*)android_os_Binder_init },
    { "destroy", "()V", (void*)android_os_Binder_destroy },
    { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};

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));
}
static struct bindernative_offsets_t
{
    // Class state.
    jclass mClass;
    jmethodID mExecTransact;

    // Object state.
    jfieldID mObject;

} gBinderOffsets;
那么,从这个方法,我们可以看到,将gBinderOffsets和Java世界android.os.Binder类,进行关联,并且指定

gBinderOffsets.mClass为android.os.Binder类

gBinderOffsets.mExecTransact为android.os.Binder.execTransact方法

gBinderOffsets.mObject对应为android.os.Binder的mObject对象所对应的值

并且,将gBinderMethods中所对应的Java世界的方法和C世界的相对应的方法一一对应

那么上述的其他两个方法,所达到的目的也是和上述方法一致,我们可以得出如下的其

<think>我们有个Java构造函数需要分析并注释。代码是: public FingerprintService(Context context) { this(context, BiometricContext.getInstance(context), () -> IBiometricService.Stub.asInterface(ServiceManager.getService(Context.BIOMETRIC_SERVICE)), () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR), null, null); } 首先,我们注意到这是个构造函数,它接受个Context类型的参数context。 在构造函数体内,它调用了同个类的另个构造函数(使用this关键字),并传递了多个参数。这些参数包括: 1. context: 传入的Context对象。 2. BiometricContext.getInstance(context): 调用BiometricContext类的静态方法getInstance,并传入context,返回个BiometricContext实例。 3. 个Lambda表达式:() -> IBiometricService.Stub.asInterface(ServiceManager.getService(Context.BIOMETRIC_SERVICE))。这个Lambda表达式定义了个提供IBiometricService接口的供应商(Supplier)。当调用时,它会通过ServiceManager获取名为Context.BIOMETRIC_SERVICE的系统服务,并将其转换为IBiometricService接口。 4.个Lambda表达式:() -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR)。同样,这是个供应商,提供通过ServiceManager获取的IFingerprint服务的多个实例(可能有多个指纹硬件)。 5. 两个null值:最后两个参数为null。 根据引用[1]和[2],Context是Android中非常重要的类,它提供了访问应用全局信息的接口。这里传入的context可能是Activity、Service或Application的Context。 引用[2]中提到,ContextWrapper是Context的包装类,而ContextImpl是真正的实现。Activity、Service等都继承自ContextWrapper,但实际工作由ContextImpl完成。 现在,我们逐行注释: ```java // FingerprintService的构造函数,需要个Context对象作为参数 public FingerprintService(Context context) { // 调用本类的另个构造函数(可能是参数更多的构造函数) // 参数1: context - 传入的上下文对象,用于访问系统资源和服务等 // 参数2: BiometricContext.getInstance(context) - 获取BiometricContext的单例,该对象可能包含与生物识别相关的上下文信息 // 参数3: 个Supplier<IBiometricService>,通过Lambda表达式实现 // 当需要IBiometricService时,会通过ServiceManager获取系统生物识别服务(BIOMETRIC_SERVICE),并转换为IBiometricService接口 // 这里使用了AIDL的Stub.asInterface来将Binder对象转换为接口 // 参数4: 个Supplier<IFingerprint[]>,通过Lambda表达式实现 // 当需要IFingerprint数组时,会通过ServiceManager获取所有声明的IFingerprint服务实例(可能有多个指纹硬件) // 参数5: null - 可能是个回调或者配置对象,这里传入null // 参数6: null - 同上 this(context, BiometricContext.getInstance(context), () -> IBiometricService.Stub.asInterface(ServiceManager.getService(Context.BIOMETRIC_SERVICE)), () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR), null, null); } ``` 注意:`ServiceManager.getService`用于获取系统服务,返回的是IBinder对象,然后通过Stub.asInterface转换成我们需要的接口类型。`ServiceManager.getDeclaredInstances`用于获取同个接口的多个实现(例如,设备可能有多个指纹传感器),返回个数组。 最后两个参数为null,说明在当前的构造需求中,这两个参数不是必须的,或者有默认值,或者可以在后续设置。 总结:这个构造函数主要用于初始化指纹服务,它依赖传入的Context,并获取了生物识别上下文、生物识别系统服务以及所有可用的指纹硬件服务。最后两个参数暂时用null传入,可能是为了扩展性预留。 相关问题: 1. BiometricContext类的作用是什么? 2. 为什么使用Supplier来延迟获取服务? 3. ServiceManager.getDeclaredInstances方法的作用是什么? 4. 在Android中,如何获取系统服务? 5. 为什么构造函数最后两个参数是null?它们可能代表什么?</think>### 分析并注释 Java 构造函数代码 ```java public FingerprintService(Context context) { // 调用本类的另个构造函数(多参数版本) this( context, // [参数1] 应用上下文,提供访问系统资源的入口 BiometricContext.getInstance(context), // [参数2] 获取生物识别全局配置的单例对象 // [参数3] Supplier 函数:延迟获取生物识别系统服务 () -> IBiometricService.Stub.asInterface( ServiceManager.getService(Context.BIOMETRIC_SERVICE) ), // [参数4] Supplier 函数:延迟获取所有已声明的指纹硬件驱动实例 () -> ServiceManager.getDeclaredInstances(IFingerprint.DESCRIPTOR), null, // [参数5] 预留参数(当前为null) null // [参数6] 预留参数(当前为null) ); } ``` ### 核心组件解析 1. **`Context context`** - Android 应用环境的核心接口[^1][^2] - 提供访问系统资源、启动组件等能力 - 实际运行时可能是 `Activity`/`Service` 等包装类,最终由 `ContextImpl` 实现具体功能 2. **`BiometricContext.getInstance(context)`** - 通过单例模式获取生物识别的全局配置对象 - 封装设备特定的生物识别参数(如传感器配置、安全策略等) 3. **Lambda 表达式 (`() -> ...`)** - **延迟加载设计**:避免服务未启动时的初始化问题 - `IBiometricService.Stub.asInterface()`:将 Binder 对象转换为 AIDL 接口 (Android 跨进程通信标准方式) - `ServiceManager.getService()`:获取系统核心服务[^4] 4. **`ServiceManager.getDeclaredInstances()`** - 动态获取同接口的多个实现(如多指纹传感器支持) - `IFingerprint.DESCRIPTOR`:硬件驱动的唯标识符 ### 设计模式分析 - **依赖注入**:通过参数传递关键依赖项 - **门面模式**:`BiometricContext` 封装复杂子系统 - **供应商模式**:Lambda 实现按需服务获取 - **空对象模式**:`null` 参数保留扩展点
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值