Android 核心分析 之七------Service深入分析

http://blog.csdn.net/maxleng/article/details/5504485

Service深入分析

 

上一章我们分析了Android IPC架构,知道了Android服务构建的一些基本理念和原理,本章我们将深入分析Android的服务。Android体系架构中三种意义上服务:

  •  Native服务
  •  Android服务
  •  Init空间的服务,主要是属性设置,这个IPC是利用Socket来完成的,这个我将在另外一章来讨论。

Navite服务,实际上就是指完全在C++空间完成的服务,主要是指系统一开始初始化,通过Init.rc脚本起来的服务,例如Service Manger service,Zygote service,Media service , ril_demon service等。

Android服务是指在JVM空间完成的服务,虽然也要使用Navite上的框架,但是服务主体存在于Android空间。Android是二阶段初始(Init2)初始化时建立的服务。

1 Service本质结构

我们还是从Service的根本意义分析入手,服务的本质就是响应客户端请求。要提供服务,就必须建立接收请求,处理请求,应答客服端的框架。我想在Android Service设计者也会无时不刻把这个服务本质框图挂在脑海中。从程序的角度,服务一定要存在一个闭合循环框架和请求处理框架

 


分析清楚服务框就必须弄清楚以下的机制及其构成。

(1)闭合循环结构放置在哪里?

(2)处理请求是如何分发和管理?

(3)处理框架是如何建立的?

(4)概念框架是如何建立的?

2 Service基本框架分析

     Android设计中,Native ServiceAndroid Service采用了同一个闭合循环框架。这个闭合循环框架放置在NativeC++空间中,,ProcessState@ProcessState.cpp IPCThreadState@IPCThreadState.cpp两个类完成了全部工作。

 

在服务框架中,ProcessState是公用的部分,这个公用部分最主要的框架就是闭合循环框架和接收到从Binder来的请求后的处理框架。我们将服务框架用ProcessSate来表示,简言之:

(1) addservice

(2) 建立闭合循环处理框架。

int main(int argc, char** argv)

{

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

addService(String16("xxx0"), new xxx0Service());

addService(String16("xxx1"), new xxx1Service());

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();//闭合循环框架

}


 

 

2.1 Native Service 

Native Service是在系统Init阶段通过Init.rc脚本建立的服务。

首先来看看一个例子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();

}

 

 

我们将代码向下展开了一层,更能看到事物的本质。

int main(int argc, char** argv)

{

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

sp<IServiceManager> sm = defaultServiceManager();

defaultServiceManager()->addService(String16("media.audio_flinger"), new AudioFlinger());

ProcessState::self()->startThreadPool();

IPCThreadState::self()->joinThreadPool();

}

 

(1)服务进程建立了ProcessState对象,并将给对象登记在进程的上下文中。

(2)建立一个新AudioFlinger对象,并将对象登记Service Manager Service中。

(3)开始就收请求,处理请求,应答这个循环闭合框架。

 

2.2 Android Service

Androids service是系统二阶段(Init2)初始化时建立的服务。

Android的所有服务循环框架都是建立SystemServer@(SystemServer.java)上。在SystemServer.java中看不到循环结构,只是可以看到建立了init2的实现函数,建立了一大堆服务,并AddService到service Manager。

main() @ com/android/server/SystemServer 

{

init1();

}

Init1()是在Native空间实现的(com_andoird_server_systemServer.cpp)。我们一看这个函数就知道了,原来这个闭合循环处理框架在这里:

init1->system_init() @System_init.cpp

 

在system_init()我们看到了这个久违的循环闭合管理框架。

{

Call "com/android/server/SystemServer", "init2"

….. 

ProcessState::self()->startThreadPool();

    IPCThreadState::self()->joinThreadPool();

}

 

Init2()@SystemServer.java中建立了Android中所有要用到的服务:

Entropy Service

Power Manager

Activity Manager

Telephony Registry

Package Manager

Account Manager

Content Manager

System Content Providers

Battery Service

Hardware Service

Alarm Manager

Init Watchdog

Sensor Service

Window Manager

Bluetooth Service

statusbar

Clipboard Service

Input Method Service

NetStat Service

Connectivity Service

Accessibility Manager

Notification Manager

Mount Service

Device Storage Monitor

Location Manager

Search Service

Checkin Service

Wallpaper Service

Audio Service

Headset Observer

Backup Service

AppWidget Service

3  ProcessState和IPCThreadState

 

从宏观来讲,PocessState及其IPCThreadState处于IPC与内核打交道包装层。前面的章节已经提到,下面我将更详细的分析。有关IPC的c++空间的实现都是从ProcessState这个对象完成的。


我们可以得出如下的结论:不管JVM的Binder做了多么复杂的操作,最终还是需要利用ProcessState 这个c++空间的对象把数据传递给Binder Driver,接收数据也是通过ProcessState这个对象完成,ProcessState是所有Binder IPC必经的通道。

 


 

ProcessState放置在全局变量gProcess中,每个进程只有一个ProcessState对象,负责打开Binder设备驱动,建立线程池等。而IPCThreadState每个线程有一个,IPCThreadState实例登记在Linux线程程的上下文附属数据中,主要负责Binder数据读取,写入和请求处理框架。IPCThreadSate在构造的时候,获取进程的ProcessSate并记录在自己的成员变量mProcess中,通过mProcess可以获取到Binder的句柄。

 

3.1 ProcessState的生命周期

      既然ProcessState是Binder通讯的基础,那么Process必须在Binder通讯之前建立。客户端,服务端都必须建立。由于现在重点讨论服务端,所以重心放置在服务端。在Android体系中有c++空间的服务,JVM空间的服务,这两类服务在本质上相同的,只是形式上不同,由于他们都是建立在ProcessState这个基础上,所以在形式上不同就仅仅表现在对OnTransact的回调处理的不同。

 

Native Service 

我们直接可以看到使用sp<ProcessState> proc(ProcessState::self()),建立建立ProcessState,一旦调用ProcessState就建立了,并且这个self将ProcessSate登记在全局变量中。

 

 

Android Service

建立Android Service服务system_init @System_init.cpp中我们可以看到相同的结构。有一点不同的是所有的Android Service都运行在一个进程中:systemsever进程。

 

3.2 Binder Driver包装 @IPCThreadState

      ProcessSate构造的时候,使用open_binder打开/driver/binder,并将句柄记录在mDriverFD,在ProcessState中并不使用这个句柄,真正使用这个Binder设备句柄的是IPCThreadState,所有关于Binder的操作放置在IPCThreadState中:

 

(1)读取/写入:talkWithDriver()@IPCThreadState对ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)进行包装。

(2)请求处理:executeCommand(...)@ IPCThreadState

(3)循环结构:joinThreadPool()

joinThreadPool()

{

While(1){

talkWithDriver(...)

...

executeCommand(...)

}

}

更多 1
相关主题推荐
android 全局变量 bluetooth 线程池 结构
相关博文推荐
打开Eclipse时出现 "Failed...
Android中打印调用栈
英最新设计“巨型泡沫体”或将治理北京雾霾
android,全部activity,整...
android手机获取手机号
android xml 三种解析
Ubuntu下android4.4.2_...
什么是对象,为什么要面向对象,怎么才能面...
查看评论
62楼 weiqiyun1986 2014-01-15 16:13发表 [回复] [引用] [举报]
佩服佩服
61楼 奋斗的蜗牛 2013-08-16 11:24发表 [回复] [引用] [举报]
层次果然高呀,看了之后立马有了清晰的框架,谢谢分享!
60楼 yisanmao19890928 2013-07-17 16:47发表 [回复] [引用] [举报]
一个字 强
59楼 smoonthsky 2012-10-30 14:24发表 [回复] [引用] [举报]
  1. select top 1 * from nb  
select top 1 * from nb
58楼 zyymcu 2012-08-21 16:20发表 [回复] [引用] [举报]
一个字 强
57楼 zyymcu 2012-08-17 11:08发表 [回复] [引用] [举报]
一个字 强
56楼 Gongqingshuai 2012-04-23 16:46发表 [回复] [引用] [举报]
怎么老提jvm Android用的是Dalvik
55楼 Jony-Li 2012-04-05 09:55发表 [回复] [引用] [举报]
up and down
54楼 skybirdcao 2012-04-01 15:17发表 [回复] [引用] [举报]
刚刚也在学习android的知识:大家可以看看这篇文档:非常棒:Android Anatomy and Physiology, 在参照例子,如果基础可以,应该是非常好文档的;推荐一下给大家
53楼 hainei_ 2012-03-07 17:01发表 [回复] [引用] [举报]
有个问题要问楼主啊,
有IXXX接口,BnXXX, BnXXX 以及 XXX 这样四个类,
通常在IXXX中发出服务请求, 在BnXXX的OnTransact函数中作出响应:
比如BnXXX::OnTransact{

case CREATE_EFFECT
sp<IEffect> effect = createEffect(pid, &desc, client, priority, output, sessionId, &status, &id, &enabled);
}

这里调用的createEffect是哪个类的呢?
Re: doremi 2013-01-30 14:08发表 [回复] [引用] [举报]
回复hainei_:去找Bnxxx的衍生类别, 您就会找到createEffect实作了.
52楼 daydreaming_111 2012-01-09 15:58发表 [回复] [引用] [举报]
对了,还有一个问题,就是system server 进程中有很多service,那么这些service 各自是如何运行的呢?它们是否跑在不同的线程呢?
Re: voipmaker 2012-03-10 20:06发表 [回复] [引用] [举报]
回复daydreaming_111:大部分服务会启动一个java线程。
51楼 daydreaming_111 2012-01-09 15:56发表 [回复] [引用] [举报]
楼组好啊,关于system server 中有一个问题,就是如果add 到 system server 中的服务,某一个出现问题,比如说挂掉了,那么请问这样对system server 有什么影响?此外,对system server 中的其他service 有没有什么影响?
50楼 mjbb55555 2011-11-25 10:36发表 [回复] [引用] [举报]
看了不下10遍,终于看懂了
49楼 ecjtu5208 2011-11-02 13:46发表 [回复] [引用] [举报]
一个字 强
48楼 crzc123 2011-10-10 15:40发表 [回复] [引用] [举报]
楼主您好,init空间的服务可否介绍一下呢,好像您漏了哦!
47楼 mcz555 2011-10-07 21:32发表 [回复] [引用] [举报]
我不知道博主这些知识是从哪里来的吗?
授人以鱼 不如授之以渔,,求源
46楼 sjm19880409 2011-09-05 16:11发表 [回复] [引用] [举报]
我发现这篇文章 和 http://blog.csdn.net/innost/article/details/6124685
这篇联系起来阅读很有效果。
45楼 zmyde2010 2011-08-26 17:40发表 [回复] [引用] [举报]
图片被CSDN吃了?
44楼 verdigrass 2011-08-23 20:05发表 [回复] [引用] [举报]
Andy Rubin应该感谢楼主啊,你把Android那么美妙的风景展示给了这么多程序员们。或许楼主还可以给他一些优化方面的建议呢。
43楼 xjx1017205114 2011-08-02 11:39发表 [回复] [引用] [举报]
跟wenservice差很大啊
42楼 stonecao 2011-08-02 11:36发表 [回复] [引用] [举报]
我有一个问题,是不是每个应用进程都会调用ProcessState::self()->startThreadPool();来启动一个线程对binder消息进行监听,systemServer我知道是有起的,System_init.cpp 中有调用,但是我们普通的应用它在哪里起的ProcessState::self()->startThreadPool(),我没有搞清楚,麻烦指点一下,谢谢!
41楼 stonecao 2011-07-28 16:24发表 [回复] [引用] [举报]
代理端调用,我大概理解调用逻辑:
java层使用binderproxy.transact调用rpc对象,对应jni封装了该native方法:
android_util_Binder.android_os_BinderProxy_transact->
BpBinder::transact->IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
binder驱动通过mHandle找到目标service把消息发送到目标进程去处理。
对于service进程如何接受并处理数据的呢?
根据你的讲解
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
我从函数名猜测,第一个函数启动一个线程池等待接受来自客户端binder消息并处理
第二个函数,本线程(主线程)的IPCThreadState对象调用joinThreadPool建立闭合消息循环来接受binder消息,接受消息后分发给前面线程池中线程去处理。
具体如何从截取消息到分发到每个service.ontransact还是没有了解清楚,希望楼主能够把这块也详细讲一下,不胜感激!
40楼 stonecao 2011-07-28 15:53发表 [回复] [引用] [举报]
楼主你好,目前我也在研究binder机制,看了你的blog,颇有收益,但是在底层binder具体如何通信的,能否写个blog给我们这些初学者详细讲解一下,谢谢!
39楼 highRAM 2011-07-11 18:57发表 [回复] [引用] [举报]
虽然看不懂,但是要MARK~~
38楼 wzhm2002 2011-07-04 22:00发表 [回复] [引用] [举报]
lz 天赋过人!!
37楼 优秀程序员 2011-05-26 15:54发表 [回复] [引用] [举报]
ok,这次读明白了[e04]
36楼 ZYSZ 2011-05-16 10:33发表 [回复] [引用] [举报]
该写本android架构啦。TW人民多出了。。。期待
35楼 sunboyljp 2011-05-09 13:24发表 [回复] [引用] [举报]
站在巨人头顶的中文翻译
34楼 徐香芋 2011-05-07 11:53发表 [回复] [引用] [举报]
哥,你看了什么武林秘籍啊?功力如此深厚![e07]
33楼 yinxuesong 2011-04-14 13:39发表 [回复] [引用] [举报]
给楼主的评价:站在巨人头顶的中文翻译[e03][e03][e10][e10]
32楼 cruel009 2011-04-08 10:28发表 [回复] [引用] [举报]
很强大,就是看不懂!
31楼 wuhualong1314 2011-03-30 00:04发表 [回复] [引用] [举报]
[e03]
30楼 denkin 2011-03-28 23:33发表 [回复] [引用] [举报]
[e10][e01][e03]
29楼 chenli_web 2011-03-24 10:41发表 [回复] [引用] [举报]
[e06],看到目标了
28楼 晓君 2011-03-07 14:14发表 [回复] [引用] [举报]
九个字 随风潜入润物细无声
27楼 容芳志 2011-03-04 16:22发表 [回复] [引用] [举报]
看了楼上们评论,我也心平气和多了
26楼 fsyiyun 2011-03-02 15:22发表 [回复] [引用] [举报]
确实看不太东,相关联的知识积累太少了~ 要努力啊&#183;~~[e03]
25楼 kaiwangkuaile 2011-02-23 14:37发表 [回复] [引用] [举报]
看不太懂,但是多看几遍就能熟悉一些吧,而且现在正需要学这个。。。
大师级别的捏,高屋建瓴
24楼 lei275437441 2011-02-21 11:12发表 [回复] [引用] [举报]
[e01][e01][e01][e01][e01]
23楼 huangwuyi 2011-02-17 09:42发表 [回复] [引用] [举报]
还是看不懂
22楼 moonsheeper 2011-02-11 13:52发表 [回复] [引用] [举报]
[e08]神马都没有看懂!
21楼 余龙飞 2011-01-22 20:18发表 [回复] [引用] [举报]
大哥,你看了什么武林秘籍啊?功力如此深厚!
20楼 liuyuan0404 2011-01-17 10:22发表 [回复] [引用] [举报]
功力不够,看不太懂啊
19楼 ljfljf2006205 2010-12-27 16:11发表 [回复] [引用] [举报]
好好理解 android 精华
18楼 Simon_foo 2010-12-16 16:27发表 [回复] [引用] [举报]
还是对ProcessSate和IPCThreadState怎样交互有些迷惑~!
不知道博主什么给解解惑。
17楼 ecorefeng 2010-12-09 18:34发表 [回复] [引用] [举报]
由此理解了android部分核心,膜拜ing[e01]
16楼 chenlaner 2010-12-07 10:30发表 [回复] [引用] [举报]
厉害,高手!
15楼 Jason_Jee 2010-11-26 11:26发表 [回复] [引用] [举报]
我们需要大师[e03]
14楼 haitang_mm 2010-09-30 14:05发表 [回复] [引用] [举报]
学习了.谢谢
13楼 xiyangfan 2010-09-26 11:48发表 [回复] [引用] [举报]
难得的教材!!!
敬佩
12楼 tianhenre 2010-09-15 16:47发表 [回复] [引用] [举报]
怎么这么强啊
好像迷路时,突然看到方向牌。
以你为镜,我好像个不知深浅的小丑。。。[e08]
11楼 flyalizee 2010-08-25 16:10发表 [回复] [引用] [举报]
自己写的继承自android.app.Service的Service跟你文中说的service是相同的东西吗,他们有与binder driver通信吗
10楼 疯狂的候鸟 2010-07-13 10:59发表 [回复] [引用] [举报]
楼主很强大,精通Linux底层通信,信号量,虚拟机啊。分析的很深刻。
9楼 匿名用户 2010-07-11 00:29发表 [回复] [引用] [举报]
教授喜欢把简单的东西弄复杂来现出他的水平让学生膜拜
Re: yinxuesong 2011-04-14 13:50发表 [回复] [引用] [举报]
回复 匿名用户:只能赞同前半句——的确是教授级别的讲解!但,是把复杂的东西,从其本质的角度,为大家讲解的!
Re: maxleng 2010-07-12 09:05发表 [回复] [引用] [举报]
回复 匿名用户:我的目的不是让人膜拜,而是分享。我本来的目的就是把代码翻译成文字和图的示意让刚刚接触Android的有个基本概念,从而在这个基础上继续前进罢了。你可以指出我的犯错的地方,大家研究,共同弄懂原理。您如果可以用更简单的描述方法描述出来,不要一个人独享,也可以让大家分享分享啊。
Re: 红尘给我滚滚 2010-11-26 11:32发表 [回复] [引用] [举报]
回复 maxleng:太底层了。 有些看不懂。。
Re: x314365164 2010-12-27 14:08发表 [回复] [引用] [举报]
回复 super005:很好的东西,底层也要懂一些.不能光只会应用层的API调用
Re: wangzhipenguestc 2010-07-31 09:36发表 [回复] [引用] [举报]
回复 maxleng:
[e03]
8楼 匿名用户 2010-07-07 17:14发表 [回复] [引用] [举报]
八个字 强大的一B吊的啊
7楼 zhangjun_44 2010-07-02 17:01发表 [回复] [引用] [举报]
膜拜!
6楼 婆婆的布鞋 2010-07-01 15:25发表 [回复] [引用] [举报]
七个字 怎么这么强大呢[e03]
5楼 李文栋 2010-06-28 17:16发表 [回复] [引用] [举报]
六个字 真他妈的强大
4楼 xiaozhi_su 2010-06-28 15:15发表 [回复] [引用] [举报]
五个字 很好很强大
3楼 freshui 2010-06-28 14:06发表 [回复] [引用] [举报]
四个字 非常强大
2楼 匿名用户 2010-06-24 18:59发表 [回复] [引用] [举报]
三个字 超强大
1楼 匿名用户 2010-05-16 14:31发表 [回复] [引用] [举报]
两个字 强大


  • 0
    点赞
  • 0
    收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页
评论
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值