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

 

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
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Android Binder 机制Android 系统中的一种进程间通信(IPC)机制,用于在不同的进程之间传递数据和调用方法。它是 Android 系统中最重要的 IPC 机制之一,也是 Android 应用程序与系统服务进行通信的基础。 Binder 机制的工作原理是基于一个抽象的客户端-服务器模型。在 Binder 机制中,有三种角色:客户端、服务器和服务管理器。客户端和服务器在不同的进程中运行,而服务管理器运行在系统服务进程中。 当客户端需要与服务器通信时,它首先通过服务管理器获取服务器的引用。服务管理器通过一个名为 Binder 驱动的内核模块来实现进程间通信。客户端可以通过跨进程访问服务器对象来调用服务器上的方法,并将参数传递给服务器。服务器可以将结果返回给客户端。 Binder 机制的一个重要特性是它支持跨进程的对象引用。这意味着客户端可以获取服务器上的对象引用,并将其传递给其他进程中的客户端。通过这种方式,多个客户端可以共享服务器上的相同对象,并相互协作。 在 Android 应用程序中,开发者可以通过 AIDL(Android 接口定义语言)来定义客户端和服务器之间的接口。AIDL 可以生成一个 Java 接口和一个 C++ 接口,用于在客户端和服务器之间进行通信。 总之,Android Binder 机制Android 系统中用于进程间通信的核心技术之一。它提供了一种高效、灵活和安全的方式来在不同的进程之间传递数据和调用方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值