android binder机制之--(我是Server Porxy)

  

服务代理对象

        上一篇android binder机制之--(我是Service Manager)我们学习了Service Manager(服务管家)在Android Binder中的作用——服务(Service)注册,服务(Service)查询和获取等功能。

        我们知道Service Manager既是服务的管理对象,又是一个系统级的服务server(通过向驱动发送设置命令,使自己成为服务管家),它用来管理系统服务,也用于向客户端体统服务。那么Service Manager的客户端(包括我们通常所说的其它系统服务和系统服务的客户端)如何同它进行通讯呢?客户端不可能凭空发送请求吧!那么在android系统中的binder肯定有实现客户端和服务端联系的机制。

        本文我们一起学习服务(Service)在客户端中的代理机制,服务代理对象就是服务端和客户端的这个联络员。在详细介绍服务代理之前,让我们先来了解一下服务代理在应用中的模型。

(一)服务代理应用模型

        下面是客户端(这里的客户端是泛指请求服务的一方,自然有时候也包括System Server,比如当System Server向Service Manager请求添加服务的时候)通过服务代理,向服务器端请求服务的模型:

(1)首先客户端向Service manager查找相应的Service。这在前一篇文中有比较详细的介绍,这里不做赘述。

(2)Android系统的binder机制将会为客户端进程中创建一个Service代理,这个创建过程是本文的重点,下面会详细介绍。

(3)客户端视角只有Service代理,他所有对Service的请求都发往Service代理,然后由Service代理把用户请求转发给Service本身。

(4)Service处理完成之后,把结果返回给Service代理,Service代理负责把处理结果返回给客户端。

        注意客户端对Service代理的调用都是同步调用(调用挂起,直到调用返回为止),这样客户端视角来看调用远端Service的服务和调用本地的函数没有任何区别。这就是我之前说的Binder机制的一个特点—线程迁移,这使得一个线程就像进入另一个线程执行并待会执行结果。

 

(二)MediaService

        要想说明白服务代理的创建过程,还真不是那么容易的,最好的办法就是参照android中的源码,一步步走下去,这里我们还是选择MediaService的应用为例吧(看过一些资料也是以MS为例介绍的)。

        MediaService是android系统中的一个应用程序,和其他普通的应用程序没什么不同,源码如下:

framework\base\Media\MediaServer\Main_mediaserver.cpp

int main(int argc, char** argv)
{
 
    sp<ProcessState> proc(ProcessState::self());
    sp<IServiceManager> sm = defaultServiceManager();
    LOGI("ServiceManager: %p", sm.get());
    AudioFlinger::instantiate();
    MediaPlayerService::instantiate();
    CameraService::instantiate();
    AudioPolicyService::instantiate();
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

        怎么样?看到这个文件的代码是不是很迷惑啊!那么多陌生的东东,怎么理解啊!那么多的难关,那么厚的面纱,看来,要想见到服务代理的创建,还得过五关斩六将啊!下面我们就来层层剥开她神秘的面纱。

(1)ProcessState

        在Android系统中任何进程,要想使用Binder机制,必须要创建一个ProcessState对象和IPCThreadState对象(不要急,这个对象我们将在后面介绍)。

        我们知道,一个客户端进程可能有多个Service的服务,这样就会创建多个Service代理(BpBinder对象,当然上面还会有封装的),那么这个进程就需要一个东东来管理这些服务代理。ProcessState就是这么个东东,它的作用就是维护当前进程中所有Service代理。

        ProcessState是一个singleton类型(关于这个类型,你可以查阅相关资料),一个进程只能创建一个他的对象。客户端进程中的ProcessState对象将会负责维护这些Service代理。那既然这样,Service代理是不是就是这个ProcessState创建的呢?呵呵,你猜对了,Service代理正是在这里被创建的,不过我可没打算现在就来分析服务代理的创建过程,你的一步一步脚踏实地地才能走向“光明”哦!

       上面的main函数中的第一句是什么?不就是这个ProcessState嘛,这里我们暂且记住一点,她就是一个管理服务代理的对象就好。先来看看她的创建过程,那就看看她的构造函数,咦,怎会回事?这个构造函数是私有成员那!

private:
  ProcessState();

        嗯,你没有看错,它的确是被声明成私有成员了,那就意味着在类的外部无法直接通过其构造函数,生成自己的一个对象,所以上面Main函数里面用了另一个公有成员函数ProcessState::self(),来调用其构造函数,生成ProcessState对象:

sp<ProcessState> ProcessState::self()
{
 
    if (gProcess != NULL) return gProcess;//如果已经创建了,//则直接返回这个全局的ProcessState对象
    AutoMutex _l(gProcessMutex);
//如果第一次创建,调用其构造函数
    if (gProcess == NULL) gProcess = new ProcessState;
    return gProcess;
}

还记得Main函数中的第一句:

sp<ProcessState> proc(ProcessState::self());

        不是说不能在外部直接调用其构造函数的吗?其实这也不是我们讨论的重点,不过既然说了,就解释一下吧。熟悉C++的朋友应该都知道,当你定义的类中,没有显示定义一个复制构造函数的话,系统会帮你添加一个默认的复制构造函数,上面的就是调用这个复制构造函数。

ProcessState::ProcessState()定义如下:
ProcessState::ProcessState()
    : mDriverFD(open_driver())   /*太高强了,竟然在初始化列表中,直接调用函数,初始化成员变量,真是不容易看到啊*/
    , mVMStart(MAP_FAILED)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
 
    ……
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);//映射内存
        ……
}

        这样就生成了一个ProcessState对象proc,用来管理本进程中所有的服务代理,当程序运行结束,proc会自动delete内部的内容,自动释放了先前分配的资源。

这里ProcessState对象打开了/dev/binder设备,并保留了文件描述符,那么打开设备文件,自然是

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值