Android Application Framework Outside, Service Understanding : 3
这是一篇旧文了,写于二零一零年七月至九月期间。当时我正在OPPO,完了电纸书项目,刚刚转入公司战略级项目,受命专职钻研Android Framework。本文即为当时的工作成果,曾以此为蓝本,组织了内部培训。本文成文后半月,我因不可抗拒原因,离开了OPPO,对Framework的研究中断,遂失去了一次专心研究Android的良机,深感痛惜。今日我把它晒出来,一来是温故旧知,二来帮助他人,但受限于既有知识,对Android的理解依旧是囫囵吞枣,文中谬误之处再所难免,恳请读者指正。
Contents
- Forward
- Android Startup
- Service Overview
- Application Service
- Android Service
- Native Service
- System (Linux) Service
- Manage Service
- Manage Android Service
- Behind ServiceManager Class
- Manage Native Service
- Behind defaultServiceManager
- Inter Process Communication
- From Java to Native
- What’s BpBinder
- 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