词条 | 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 |
随便看 |
百科全书收录4421916条中文百科知识,基本涵盖了大多数领域的百科知识,是一部内容开放、自由的电子版百科全书。