android binder机制之——(我是binder实例)

本文详细剖析了Android中Binder机制的Java层应用,包括ServiceManager的获取与使用,以及Camera模块的binder通信分析。首先介绍了Java层如何通过JNI调用C/C++代码创建服务代理对象,接着详细阐述了ServiceManager的获取过程。接着,文章以Camera模块为例,展示了服务端启动、客户端联系建立及数据传输流程,揭示了binder机制如何实现进程间通信。
摘要由CSDN通过智能技术生成
 

Binder应用实例

        前一篇文章我们从进程的C/C++层面讲解了binder机制的服务代理对象BpBinder的获取,和Binder底层处理方法。整个服务代理的获取过程也是binder机制的的核心内容,它涉及到了客户请求,请求的传递和处理,服务代理的生成和转换(封装)过程。当客户端获取到对应服务的代理后,就可以通过这个服务代理和服务端通讯了。

        本文我们将以binder机制在android中的应用实例,来分析客户端与服务器端的通讯整个流程。不过,在介绍实例前,我们还要花点时间来分析一下binder机制在进程的Java层面服务代理对象的创建和使用。

(一)binder机制中的Java层

        我们知道Android中的应用程序基本上都是java开发,对Android的框架了解的朋友都知道,Java的本地实现都是通过JNI层的接口来调用C++/C代码的,这里也不例外。在android的binder机制中,Java层面的binder机制的应用,你可以简单看作是底层binder机制的封装。

        Binder客户程序的C/C++层面的对象和原理我们在前面我们已经学习过,下面我们将介绍客户程序怎样在Java层面通过JNI调用底层C/C++代码的创建服务代理的。

(1)ServiceManager类型和对象

        我们都知道,作为客户端要想获得服务代理,首先要向ServiceManager查询Service,然后创建并返回服务代理对象,再通过代理对象和Service通讯。当然,在Java层面也是这样,所以客户端首先也要获取ServiceManager这个系统服务的服务代理,再同这个代理来查询并请求服务,所以我们首先分析Java层面ServiceManager类。

Framework\base\core\android\os\ServiceManager.java

public final class ServiceManager {
 
    private static final String TAG = "ServiceManager";
private static IServiceManager sServiceManager;
……

       上面是ServiceManager类定义,可以看出来ServiceManager也是一个Singleton类型。(成员函数代码暂不贴出来,可以参考源码)所有的方法都是静态方法,包括上面的sServiceManager成员变量(这意味着所有的ServiceManager对象,共享这个变量)。而所有静态方法都是通过调用它的IServiceManager类型的静态变量sServiceManager来实现的。

  

       所以可以理解ServiceManager就是IServiceManager对象的一个代理,它就是一个对sServiceManager封装的一个类。因为创建和访问这个变量都是通过ServiceManager的getIServiceManager方法,定义如下:

private static IServiceManager getIServiceManager() {
 
        if (sServiceManager != null) {
 
            return sServiceManager;
        }
 
        // Find the service manager
        sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
        return sServiceManager;
    }

        sServiceManager是一个IserviceManager类型,如果它已经创建,就直接返回,否则,创建并返回。当然第一次进入这个函数,是要创建的了,下面就来看看它的具体创建过程吧! 

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

        还是老规矩,首先分析asInterface的参数BinderInternal.getContextObject(),哇,好长的参数,必须把丫解了。看到BinderInternal没有,这是什么呢?呵呵,用鼠标就知道了(用source insight的都知道)。

Framework\base\core\com\java\android\os\BinderInternal.java

public class BinderInternal {
 
……
/**
     * Return the global "context object" of the system.  This is usually
     * an implementation of IServiceManager, which you can use to find
     * other services.
     */
 
public static final native IBinder getContextObject();
……

        这里可以看到BinderInternal类的getContextObject方法的代码,惊奇的发现是Native代码,这不就是Java的本地接口嘛!这下好了,它通过调用JNI层的某个文件的代码(而且是C++的代码),来和底层的C++/C实现挂钩。至于它怎么和JNI层的的函数对应的调用的,我相信你早已心知肚明了,这里不做介绍。

        BinderInternal类中的本地接口的JNI实现文件,就是android_util_binder.cpp文件,getContextObject方法在该文件中对应的函数是android_os_BinderInternal_getContextObject函数,代码如下:

Framework\base\core\jni\android_util_binder.cpp

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
 
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    return javaObjectForIBinder(env, b);
}

         还记得这个ProcessState对象吗?就是那个管理整个进程的服务代理对象的那个玩意,一个进程只能有一个该类对象的。既然它管理服务代理对象,那这个服务代理对象创建也应该跟她有关系了,事实上,从前文的分析已经看出来的却是这样。虽然前文已经有所述,这里再加强下记忆吧,我们再去查看ProcessState对象的getContextObject方法,代码如下:

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
 
    if (supportsProcesses()) {
 
        return getStrongProxyForHandle(0);
    } else {
 
        return getContextObject(String16("default"), caller);
    }
} 

         就是这里,我们看到在当前进程的ProcessState对象,其实是调用getStrongProxyForHandle方法,来创建binder句柄为0的服务代理对象——BpBinder对象的,我们知道ServiceManager的binder句柄就是这个个闻名句柄0。

哦,这里不又是回到前文的内容里了嘛!再说一边就没有意思了,如果忘记了,可以回头看看,呵呵,还是要“经常回头看看自己走过的路。”

        我们可以看出Java调用C/C++,创建一个服务代理对象BpBinder,在查看BpBinder的定义我们发现继承自IBinder接口,然后在android_util_binder.cpp中的方法android_os_BinderInternal_getContextObject中,把C/C++层面的IBinder对象封装成Java层面的IBinder对象。

        至此我们已经清楚BinderInternal.getContextObject(),返回的是ServiceManager的服务代理对象——BpBinder对象。那么ServiceManagerNative类的静态方法asInterface做什么用呢?这个貌似和我们前面讲过的内容不太一样。还记得在C/C++层面的获取服务代理的流程吧,在创建了一个BpBinder代理对象后,是不是通过一个类型转换函数将这个代理对象转换成了IserviceManager对象(当然,这里是C++类的对象),我们还重点分析了那个转换函数,其实你知道的,那是个宏定义:

gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));     //创建代理对象

就是这段代码,既然也走到了这里,他们的参数一样,唯一不同的就是这个主体函数喽!那么我们Java层面的这段代码: 

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

        是不是也

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值