Android Application Framework Outside, Service Understanding : 3

这是一篇旧文了,写于二零一零年七月至九月期间。当时我正在OPPO,完了电纸书项目,刚刚转入公司战略级项目,受命专职钻研Android Framework。本文即为当时的工作成果,曾以此为蓝本,组织了内部培训。本文成文后半月,我因不可抗拒原因,离开了OPPO,对Framework的研究中断,遂失去了一次专心研究Android的良机,深感痛惜。今日我把它晒出来,一来是温故旧知,二来帮助他人,但受限于既有知识,对Android的理解依旧是囫囵吞枣,文中谬误之处再所难免,恳请读者指正。

Contents

  1. Forward
  2. Android Startup
  3. Service Overview
    1. Application Service
    2. Android Service
    3. Native Service
    4. System (Linux) Service
  4. Manage Service
    1. Manage Android Service
    2. Behind ServiceManager Class
    3. Manage Native Service
    4. Behind defaultServiceManager
  5. Inter Process Communication
    1. From Java to Native
    2. What’s BpBinder
    3. What’s BBinder

Manage Service

大千世界,具体到社会运作,抽象至软件运行,不以规矩,不成方圆 ,所有的一切都要接受约束和管理,在一系列规则下生存。那么Android中众多的service又是如何被管理的?

Manage Android Service

Service要在Android系统中发挥作用,首先要解决一个问题:Android是如何使其成为系统服务的。

以AlarmManagerService为例,观察构造函数的调用位置,那么可以发现其出现在com.android.server.ServerThread,与此相似,很多Service的构造函数都出现在com.android.server.ServerThread。但是,令人奇怪的是,无论如何也找不到ServerThread.java这么一个文件,实际上它躲藏在SystemServer.java中。

注意:多个class声明在同一个文件里是一种不值得推荐的做法,尽管Android中这种做法并不少见。

ServerThread并不是一个多么神秘的类,仅仅是java.lang.Thread的子类,其使命就是在新起的线程上实例化服务,然后把它们加入到android.os.ServiceManager中进行统一管理,如图表7所展示。

图表 7(frameworks/base/services/java/com/anroid/server/SystemServer.java)

一个不被使用的service是没有价值的,在解决了如何成为系统服务之后,还需要解决另外一个问题,那就是如何获取系统服务。前面提到ServiceManager提供了addService方法实现了向系统中添加服务的功能,同样它提供了getService方法实现从系统中获取服务的功能。

以android.app.ContextImpl中获取电源管理服务为例,首先从getService方法中获取服务对应的IBinder,然后通过asInterface方法获得服务实例。通用做法同图表8所示。

图表 8(frameworks/base/core/java/android/app/ContextImpl.java)

Behind ServiceManager Class

ServerThread在SystemServer的init2方法中被启动,奇怪的是,却怎么也不见init2是在哪里被调用的?

SystemServer的main方法是入口,libandroid_servers.so被加载进来以后调用其中的本地方法init1。通过过com_android_server_SystemServer.cpp 可以知道其把init1的调用委托给了system_init方法,而这个方法是在system_init.cpp中实现的,在该方法的末尾,可以看到如下信息:

图表 9(frameworks/base/cmd/system_server/library/system_init.cpp)

图表9解释了玄机,在init1执行将结束时,SystemServer的init2被调用。ServerThread被调用start方法以后,进入到run方法当中,服务被创建,通过ServiceManager.addService添加到IServiceManager当中。

但是也引发了一个新的疑问:ServiceManager是如何实现管理功能的呢?

经过静态代码分析,可以发现ServiceManager.java并不是实现服务管理的真正“主谋”,ServiceManager将调用转发给了ServiceManagerNative,而ServiceManagerNative又将其转包,交给了ServiceManagerProxy。

从代码上看,ServiceManagerProxy最终还是借助IBinder完成了它的职责,如图表10所示。

图表 10(frameworks/core/java/android/os/ServiceManagerNative.java)

我们对service使用IPC感到司空见惯,现在发现ServiceManager一样离不开IPC,–是不是ServiceManager也是一种service呢?通常当看到IPC后,思考就停止了,这已经到了Android的底层。但是,浅尝则止永远不会进步。对问题穷根究底,就会发问:IPC到底是怎么运作的?

Manage Native Service

由上可见,ServiceManager类提供了管理Android Service的功能,但是,对于Native Service又是如何处理呢?

在图表5中,MeideaPlayerService调用了instantiate方法,注释中标明“Start the media playback service”,这表明服务被开启了,如果进入到instantiate方法,可以发现:

图表 11(frameworks/media/libmediaplayerservice/MediaPlayerService.cpp)

图表11展示了Native Service是如何被加入到ServiceManager中进行管理,接下图表12展现了如何从ServiceManager中获取Native Service。

图表 12(frameworks/base/cmd/stagefright/stagefright.cpp)

Behind defaultServiceManager

出现在上节当中的defaultServiceManager是如何得到IServiceManager的呢?这就要追踪到源码了。

图表 13 (framework/base/libs/binder/IServiceManager.cpp)

当进程首次运行到图表13时,gDefaultServiceManager肯定是为NULL,因此肯定是要执行ProcessState::self()。

图表 14 (framework/base/libs/binder/ProcessState.cpp)

图表14可以得出一个结论:一个进程只有一个ProcessState对象,而在创建对象的过程中,调用open_driver方法为mDriverFD赋值,也就是在open_driver中,进程打开了/dev/binder。

回过头来再来看ProcessState类的成员函数getContextObject,根据代码的执行流程,可以判断出其最终进入到成员函数getStrongProxyForHandle中。

图表 15 (framework/base/libs/binder/ProcessState.cpp))

由以上的代码来看,最终得到的是BpBinder的指针,那么接下来的interface_cast又到底做了什么呢?

图表 16(framework/base/include/binder/IInterface.h)

至此真相即将揭开了,asInterface如图表17所示。

图表 17 (framework/base/include/binder/IInterface.h)

那么这个宏到底是怎么使用的呢?

图表 18(framework/base/libs/binder/IServiceManager.cpp)

在从中可以看到,最后得到的是一个BpServiceManager

Leave a comment

Your comment