当前位置:在线查询网 > 在线百科全书查询 > Android内核剖析

Android内核剖析_在线百科全书查询


请输入要查询的词条内容:

Android内核剖析




基本信息


出版社: 电子工业出版社; 第1版 (2011年9月1日)

作者:柯元旦其他: 616页

ISBN: 9787121143984

条形码: 9787121143984

字数:1109千字

页码:616

开本:16

图书简介


本书详细分析了Android内核的内部机制,包括窗口管理系统、Activity管理系统、输入法框架、编译系统等,为Android内核定制及高级应用程序开发提供技术参考。

本书适合于所有Android相关的工程师及产品经理,还可作为相关培训机构的教材。

1. 什么是Android内核

Android操作系统是基于Linux实现的,然而Android的核心价值却不是Linux,所以说,Android的内核不是指Linux,本书不是一本介绍Linux的书。这就好比苹果的操作系统iOS是基于Unix实现的,然而iOS的核心价值却不是Unix。

那么,Android的内核是什么,它的核心价值都包含什么?

大家听过和Android内核最多的词语应该是“Android Framework”以及“Dalvik虚拟机”,那么,这两个核心部分从内部运行机制的角度来看,到底扮演着什么角色,彼此之间如何协同工作呢?了解清楚了这些,也就了解了所谓Android的核心价值,即Android内核。

从进程的角度来看,Android的运行环境如下图所示:

当Linux内核启动后,此时系统的状态和普通的Linux系统基本相同,通过配置Linux中的init.rc文件,可以指定内核启动后都要执行什么程序,而这之后所启动的程序才是Android系统和普通Linux应用系统的区别。

init.rc中所启动的一个重要进程被称作zygote进程,如上图中红色边框所示,zygote这个英文单词的意思是“受精卵”,本书将其称为“种子进程”,从进程的角度来看,种子进程仅仅是一个Linux进程而已,它和一个只包含main()函数的C程序所产生的进程是同一个级别,如上图中双实线边框所示。

种子进程里面所运行的程序基本上就是Android内核的精华所在,其内部主要完成了两件事情。第一件事情是装载了一段程序代码,这些代码都是用C语言写的,这段代码的作用只是为了能够执行Java编译器编译出的字节码,这段代码就是传说中的Java虚拟机,在Android中称为Dalvik虚拟机。

第二件事情必须基于第一件事情之后,即当Dalvik虚拟机代码初始化完成后,从一个名为ZygoteInit.java类中的main()函数中开始执行。这里大家就奇怪了,Dalvik虚拟机如何知道ZygoteInit这个Java类在哪个Jar包里面?实际上,这个Jar包的目录位置信息正是在init.rc中进行配置的,只不过没有直接指定,而是使用一个标志符,当这个标志符是“zygote”时,Dalvik虚拟机就会从“硬编码”的字符串中得到ZygoteInit类所在的Jar包,而这个Jar包正是framework.jar。

接下来的事情即是简单的,又是复杂的。所谓简单是指,ZygoteInit类中main()函数所做的事情和Linux本身就没多大关系了,理论上完全可以在该main()函数中实现任意简单的功能;所谓复杂是指,该main()函数中才刚刚开始启动Android的核心功能。

在ZygoteInit类中的main()函数中,首先加载一些类文件,这些类将作为以后所有其它Apk程序共享的类,接着,会创建一个Socket服务端,该服务端将用于通过Socket启动新进程。

该进程之所以被称为“种子”进程的原因就是,当其内部的Socket服务端收到启动新的Apk进程的请求时,会使用Linux的一个系统调用folk()函数从自身复制出一个新的进程,新进程和Zygote进程将共享已经装载的类,这些类都是在framework.jar中定义的。

以上从进程的角度分析了Android内核的概念,下面从图形用户界面的角度再来看看Android内核的含义。大家都知道,Linux内核所提供的功能主要包括:

l 进程调度

l 内存管理

l 驱动模型

这些功能都是和用户界面没有关系的,内核一般仅仅会通过USB接口或者RS232串口输出一些状态信息,而对于窗口操作系统而言,这还远远不够,最重要的就是操作系统应该提供一套用户界面子系统,该子系统包含如何创建、删除窗口,以及用户如何和窗口进行交互,同时还应该提供一套界面程序库,以便第三方开发商能够基于该界面库快速的开发一些窗口应用程序。而这就是Android最核心的内容,完成这些功能的代码大部分都在那个framework.jar文件中,Dalvik虚拟机只不过是执行这些功能代码的一个环境而已。

因此,如果考虑图形用户界面,则一个Android应用程序的内部关系如下图所示:

首先,内部模块可分为三个大部分,分别是:

第一部分,Linux驱动端。该模块重新把标准Linux驱动抽象为Android所定义的硬件接口,从而保持了Android内核代码的独立性,即当Linux驱动有变动时,只需要修改该适配层,而不需要再修改Android内核的代码。该驱动端也被称作硬件抽象层(Harware Abstarction Layout)。

第二部分,Framework服务端,该服务端主要进行输入消息的处理,并将消息传递给窗口管理服务线程(WmS),WmS内部会根据当前所有应用窗口的层次关系,决定应该把这个消息派发给哪个窗口。除了WmS外,还包含一个核心线程组件,即Activity管理线程(AmS),Activity是Android中定义的一个程序片段,这个片段可理解为“可以被动态加载的程序”,即,当应用线程启动后,可以根据用户的操作,有选择的加载不同的Activity。

第三部分,Apk应用程序客户端。每一个Apk应用程序的客户端都是从ActivityThread类中的main()函数开始执行,这和一个普通的Java程序完全相同,当ActivityThread启动后,会向AmS报告说“自己已经启动了,请告诉我要执行哪一个Activity片段”,AmS会通过进程间通信(Inter Process Communication)的方式把要加载的Activity信息告诉给ActivityThread,从而ActivityThread执行指定的Activity,而在Activity内部会调用Framework中提供的各种添加窗口的函数进行窗口的添加和删除。

Android内核剖析就是围绕以上过程进行彻底的剖析。

2. Android内核剖析的思路

了解了以上Android内核的定义后,自然会想到以下问题,同时,问题会再被细化更多问题,比如?

l 什么是一个Apk程序,该Apk程序是怎么被编译出来的,ActivityThread中是如何加载该Apk程序的?

l 当用户在屏幕上点击一个应用图标后,消息如何被传递到AmS中,AmS又是如何知道该图标对应的信息,以及如何启动对应的Apk进程?

l 应用进程中Activity内部如何添加一个应用窗口,该窗口在WmS内部如何被保存,当一个触摸消息发生后,WmS如何知道这个消息对应哪个窗口?

l 在应用程序内部,一个ViewGroup对象以及一个View对象是如何被绘制到屏幕上,onDraw()是如何被调用的?

l OptionMenu、ContextMenu和Dialog添加窗口的方式有什么不同?

l 什么是一个Context对象,它与Activity之间是什么关系?

l Activity、“窗口”、Window、View,这些概念或者类在代码上是什么关系?

l 资源文件是如何被加载的,系统资源和应用资源是什么关系?如何改变加载系统资源的路径从而达到替换系统资源的目的?

l 输入法窗口和普通应用窗口之间的关系如何?为什么输入法管理器没有提供查询输入法窗口大小的接口,以及为什么不提供查询是否输入法窗口显示在界面上的接口?

l 如何编写一个新的输入法?

l AndroidManifest.xml中申请的权限是如何保存在系统中的,这些权限在运行时是如何被检查的?

l Apk是如何被安装和卸载的?

l framework.jar包是如何被编译出来的,如何添加一些私有的framework类,并不把这些类暴露给SDK?

l 如何编译不同的子工程,比如Linux动态库、静态库、Jar包等?如何给Java工程中增加JNI代码并编译?

l 有没有可能把framework改造为没有界面的系统,仅运行一些后台服务?

l 如何给Android增加一个外部显示器的功能?

这里仅仅列出一些常见的问题,也仅仅是一些问题入口,在具体分析一个问题是又会引出新的问题,本书作者分析的思路也是如此,但在目录安排上则是将分析后的结果按照内在的关系重新组织在一起。

3. 本书目标

从工程的设计需要来讲,本书适合的目标群体如下图绿色部分所示,红色部分为不适合的读者对象,黄色表示本书未来会增加的内容。

4. 读者对象

由于Android内核剖析的本质不是剖析Linux,因此,本书的读者不需要有任何Linux基础,而只要熟练使用C语言和Java语言即可。

另外,从作者对iOS应用层的分析来看,其图形用户界面(GUI)的设计架构思想和Android有非常相似的地方,而iOS不是开源的,因此,iOS的开发者也可以参考本书来理解一些GUI内部机制,从而有助于上层的应用开发。

图书目录


第1部分 基础篇

第1章 Linux基础 2

1.1 Linux文件系统概述 2

1.2 Linux启动过程 4

1.3 常用Linux 命令 6

1.4 Shell脚本备忘 9

1.5 Make脚本备忘 15

第2章 Java基础 26

2.1 类装载器DexClassLoader 26

2.2 JNI调用机制 32

2.3 异步消息处理线程 37

第3章 Android源码下载及开发环境配置 44

3.1 Mac系统的配置 44

3.2 在Linux中配置USB连接 46

3.3 在Eclipse中调试Framework 46

第4章 使用git 51

4.1 安装git 52

4.2 git仓库管理 52

4.3 git merge用法 57

4.4 git rebase用法 58

4.5 git cherry-pick用法 61

4.6 git reset用法 62

4.7 恢复到无引用提交 63

4.8 git remote用法 65

4.9 git 配置 67

4.10 同时使用git和svn 71

4.11 其他git常用命令示例 72

第2部分 内核篇

第5章 Binder 78

5.1 Binder框架 78

5.2 设计Servier端 80

5.3 Binder客户端设计 81

5.4 使用Service类 82

5.5 系统服务中的Binder对象 88

第6章 Framework概述 92

6.1 Framework框架 92

6.2 APK程序的运行过程 94

6.3 客户端中的线程 94

6.4 几个常见问题 95

第7章 理解Context 98

7.1 Context是什么 98

7.2 一个应用程序中包含多少个Context对象 99

7.3 Context相关类的继承关系 99

7.4 创建Context 100

第8章 创建窗口的过程 106

8.1 窗口的类型 106

8.2 token变量的含义 108

8.3 创建应用窗口 111

8.4 创建子窗口 121

8.5 系统窗口Toast的创建 136

8.6 创建窗口示例 139

第9章 Framework的启动过程 142

9.1 Framework运行环境综述 142

9.2 Dalvik虚拟机相关的可执行程序 143

9.3 zygote的启动 147

9.4 SystemServer进程的启动 155

第10章 AmS内部原理 160

10.1 Activity调度机制 160

10.2 内存管理 192

10.3 对AmS中数据对象的理解 211

10.4 ActivityGroup的内部机制 214

第11章 从输入设备中获取消息 221

11.1 Android消息获取过程概述 221

11.2 与消息处理相关的源码文件分布 223

11.3 创建InputDispatcher线程 226

11.4 把窗口信息传递给InputDispatcher线程 227

11.5 创建InputChannel 229

11.6 在WmS中注册InputChannel 232

11.7 在客户进程中注册InputChannel 233

11.8 WmS中处理消息的时机 234

11.9 客户窗口获取消息的时机 235

第12章 屏幕绘图基础 237

12.1 绘制屏幕的软件架构 237

12.2 Java客户端绘制调用过程 239

12.3 C客户端绘制过程 241

12.4 Java客户端绘制相关类的关系 244

第13章 View工作原理 247

13.1 导论 247

13.2 用户消息类型 249

13.3 按键消息派发过程 252

13.4 按键消息在WmS中的派发过程 263

13.5 触摸消息派发过程 266

13.6 导致View树重新遍历的时机 274

13.7 遍历View树performTraversals()的执行过程 293

13.8 计算视图大小(measure)的过程 296

13.9 布局(layout)过程 308

13.10 绘制(draw)过程 313

13.11 动画的绘制 331

第14章 WmS工作原理 340

14.1 概述 340

14.2 WmS主要内部类 348

14.3 窗口的创建和删除 355

14.4 计算窗口的大小 371

14.5 切换窗口 379

14.6 perforLayoutAndPlaceSurfacesLockedInner()的执行过程 398

14.7 窗口动画 406

14.8 屏幕旋转及Configuration的变化过程 409

第3部分 系统篇

第15章 资源访问机制 414

15.1 定义资源 414

15.2 存储资源 415

15.3 styleable、style、attr、theme的意义 417

15.4 AttributeSet与TypedArray类 420

15.5 获取Resources的过程 425

15.6 Framework资源 431

第16章 程序包管理(Package Manager Service) 439

16.1 包管理概述 439

16.2 packages.xml文件格式 442

16.3 包管理服务的启动过程 446

16.4 应用程序的安装和卸载 455

16.5 intent匹配框架 463

第17章 输入法框架 467

17.1 输入法框架组成概述 468

17.2 输入法中各Binder对象的创建过程 469

17.3 输入法主要操作过程 477

17.4 输入法窗口内部的显示过程 490

17.5 向编辑框传递字符 503

17.6 输入法相关源码清单 504

第4部分 编译篇

第18章 Android编译系统 508

18.1 Android源码文件结构 509

18.2 从调用make命令开始说起 509

18.3 编译所需脚本文件之间的协同关系 512

18.4 如何增加一个product 523

18.5 如何增加一个项目 528

18.6 APK编译过程 533

18.7 Framework的编译 544

18.8 编译android.jar 547

18.9 编译adt插件 553

18.10 总结 554

第19章 编译自己的Rom 555

19.1 嵌入式系统的内存地址空间 555

19.2 各种映像(Image)文件的作用 559

19.3 编译Nexus S(NS)的Image文件 562

19.4 使用fastboot写入Image文件 566

19.5 最后验证 567

第5部分 硬件驱动篇

第20章 基于TI OMAP处理器的 Techshine 开发板介绍 573

20.1 Techv-35XX开发板概述 574

20.2 交叉编译环境配置 575

20.3 x-loader编译 578

20.4 u-boot编译 578

20.5 Techv-35XX Linux驱动和内核配置及编译 579

20.6 Techv-35XX Android驱动编写 584

20.7 Techv-35XX Android开发环境建立 589

20.8 编译Android Donut 590

20.9 Android根文件系统的制作 591

20.10 相关Image文件的烧写 591

20.11 Android 根文件系统安装 593

相关分词: Android 内核 剖析