深入理解Android 5 源代码(txt+pdf+epub+mobi电子书下载)


发布时间:2020-05-09 11:14:54

点击下载

作者:李骏

出版社:人民邮电出版社

格式: AZW3, DOCX, EPUB, MOBI, PDF, TXT

深入理解Android 5 源代码

深入理解Android 5 源代码试读:

前言

Android是一款基于Linux平台的开源手机操作系统,该平台由操作系统、中间件、用户界面和应用软件组成,号称是首个为移动终端打造的真正开放的操作系统。本书的内容

Android系统是Google研发团队集体智慧的结晶,拥有着海量的源代码。本书受篇幅的限制,只分析了Android系统中的一些主要模块和类,并对主要模块的细节进行了全面分析,而相似部分并没有进行详细阐述。这样可以确保读者在有限的篇幅中了解Android的内部结构和运行机制,同时避免读者陷入海量代码的云雾中而不得要领的情况发生。

另外,由于Android系统升级较快,有些代码变动很大。虽然Android系统自2008年9月发布第一个版本1.1以来,截至2014年10月发布最新版本5.0,一共存在十多个版本。在本书的讲解中,选择了本书写作时的最新版本Android 5.0系统,这样可以体验Android系统的最新功能。

全书共分20章,涵盖了Android系统主要的源代码,如HAL系统、IPC通信机制、Binder对象、init进程和Zygote进程、System进程和应用程序进程、Activity组件、Content Provider、Broadcast、电源管理、电话系统、短信系统、传感器、SEAndroid、ART等核心技术。为了帮助读者学以致用,对于重点的模块都会详细剖析其原理和实现的过程,以便读者在自己的项目开发中可以借鉴。本书特色

本书内容丰富,分析细致,我们的目标是通过一本图书,提供多本图书的价值。在内容的编写上,本书具有以下特色。(1)结构合理

从用户的实际需要出发,科学安排知识结构,内容由浅入深。全书详细地讲解了和 Android应用开发有关的源代码结构。(2)易学易懂

本书条理清晰、语言简洁,可帮助读者快速掌握每个知识点。读者既可以按照本书编排的章节顺序进行学习,也可以根据自己的需求对某一章节进行有针对性的学习。(3)实用性强

本书彻底摒弃枯燥的理论,注重实用性和可操作性,详细讲解了各个知识点的基本知识。读者对象

初学Android编程的自学者;

大中专院校的老师和学生;

毕业设计的学生;

Android编程爱好者;

相关培训机构的老师和学员;

从事Android开发的程序员。

本书在编写过程中,得到了人民邮电出版社工作人员的大力支持,正是各位编辑的求实、耐心和效率,才使得本书在这么短的时间内出版。另外,也十分感谢我的家人,在我写作的时候给予的巨大支持。另外,本人水平毕竟有限,书中的纰漏和不尽如人意之处在所难免,诚请读者提出意见或建议,以便修订并使之更臻完善。另外,本书的答疑和技术交流网站为http://www.toppr.net/,读者如有疑问可以在此提出,一定会得到满意的答复。作者

第1章 Android系统介绍

2007年,Google公司推出了一款移动智能设备系统——Android,这是一种建立在 Linux 基础之上的为手机、平板电脑等移动设备提供的软件解决方案。截止到2013年,根据知名IDC公司的统计,Android系统在世界智能手机发货量中占据75%的份额,已经成为了当今最受欢迎的智能设备系统之一,2014年更是达到了84.4%。在本章将引领读者一起来了解Android系统的发展历程,充分了解这款操作系统的成功之处。

1.1 Android系统成功的秘诀

Android系统为什么能够在这么短的时间内成为移动智能设备市场占有率的老大?在本节的内容中,将从4个方面来为读者解答这个问题。

1.1.1 获取了业界的广泛支持

Android系统基于Linux内核,是一款开源的手机操作系统。正是因为如此,在Android刚刚崭露头角之后,各大手机厂商和电信部门纷纷加入到了Android联盟当中。Android联盟由业界内的世界级企业组成,主要成员包括中国移动、摩托罗拉、高通、T-Mobile、三星、LG、HTC等在内的30多家技术和无线应用的领军企业。Android通过与运营商、设备制造商、开发商和其他有关各方结成深层次的合作伙伴关系,希望借助建立标准化、开放式的移动电话软件平台,在移动产业内形成一个开放式的生态系统。

1.1.2 研发阵容强大

Android的研发队伍阵容强大,包括摩托罗拉、Google、HTC(宏达电子)、PHILIPS、T-Mobile、高通、三星、LG及中国移动在内的34家企业,他们都将基于该平台开发手机的新型业务,应用之间的通用性和互联性将在最大程度上得到保持。

1.1.3 为开发人员“精心定制”

Google公司一直视程序员为前进动力的源泉,为了提高程序员们的开发积极性,不但为开发人员提供了一流的开发装备和软件服务,而且还提出了振奋人心的奖励机制。(1)保证开发人员可以迅速转型到Android应用开发

Android应用程序是通过Java语言开发的,只要具备Java开发基础,就能很快上手。作为单独的Android应用开发,对Java编程门槛的要求并不高,即使没有编程经验的初学者,也可以在突击学习Java之后平滑地过渡到Android开发上来。另外,Android完全支持2D、3D和数据库,并且和浏览器实现了集成。所以,通过Android平台,程序员可以迅速、高效地开发出绚丽多彩的应用。(2)定期召开奖金丰厚的Android大赛

为了吸引更多的用户使用Android开发,Google已经成功举办了奖金为数千万美元的开发者竞赛。鼓励开发人员创建出创意十足、十分有用的软件。这种大赛对于开发人员来说,不但能提高自己的开发水平,并且高额的奖金也是学员们学习的动力。(3)开发人员可以利用自己的应用赚钱

为了能让Android平台吸引更多的关注,Google提供了一个专门下载Android应用的商店:Android Market,地址是https://play.google.com/store。在这个商店里允许开发人员发布应用程序,也允许Android用户下载获取自己喜欢的程序。作为开发者,需要申请开发者账号,申请后才能将自己的程序上传到Android Market,并且可以对自己的软件进行定价。只要你的软件程序足够吸引人,你就可以获得很好的金钱回报。这样实现了程序员学习和赚钱两不误,所以吸引了更多开发人员加入到Android大军中来。

1.1.4 开源

Android是一款开源的系统,开源意味着对开发人员和手机厂商来说是完全无偿免费使用的。正是因为这一原因,吸引了全世界各地无数程序员的热情。于是很多手机厂商都纷纷采用Android作为自己产品的系统。因为免费所以降低了成本,提高了利润。而对于开发人员来说,因为Android深受众多移动设备产品所采用,所以这方面的人才也变得愈发得到重视。

1.2 剖析Android系统架构

Android系统是一个移动设备的开发平台,其软件层次结构包括操作系统(OS)、中间件(MiddleWare)和应用程序(Application)。根据 Android 的软件框图,其软件层次结构自下而上分为以下4层。(1)操作系统层(OS)。(2)各种库(Libraries)和Android运行环境(RunTime)。(3)应用程序框架(Application Framework)。(4)应用程序(Application)。

上述各个层的具体结构如图1-1所示。

在本节的内容中,将详细介绍Android操作系统的组件结构方面的知识。▲图1-1 Android操作系统的组件结构图

1.2.1 底层操作系统层(OS)

因为Android源于Linux,使用了Linux内核,所以,Android使用Linux 2.6作为操作系统的基础。Android对操作系统的使用包括核心和驱动程序两部分,Android内核对应于Linux内核, Android更多的是需要一些与移动设备相关的驱动程序。主要的驱动如下所示。

显示驱动(Display Driver):是常用的基于Linux的帧缓冲(Frame Buffer)驱动。

Flash内存驱动(Flash Memory Driver):是基于MTD的Flash驱动程序。

照相机驱动(Camera Driver):常用基于Linux的V4L(Video for Linux)驱动。

音频驱动(Audio Driver):常用基于ALSA(Advanced Linux Sound Architecture,高级Linux声音体系)驱动。

WiFi驱动(Camera Driver):基于IEEE 802.11标准的驱动程序。

键盘驱动(KeyBoard Driver):作为输入设备的键盘驱动。

蓝牙驱动(Bluetooth Driver):基于IEEE 802.15.1标准的无线传输技术。

Binder IPC驱动:Andoid一个特殊的驱动程序,具有单独的设备节点,提供进程间通信的功能。

Power Management(能源管理):用于管理电池电量等信息。

1.2.2 各种库(Libraries)和Android运行环境(RunTime)

本层次对应一般嵌入式系统,相当于中间件层次。Android的本层次分成两个部分,一个是各种库,另一个是Android运行环境。本层的内容大多是使用C实现的,其中包含了如下所示的各种库。

C库:C语言的标准库,也是系统中一个最为底层的库,C库是通过Linux的系统调用来实现。

多媒体框架(MediaFrameword):这部分内容是 Android 多媒体的核心部分,基于PacketVideo(即 PV)的 OpenCORE,从功能上看本库一共分为两大部分,一部分是音频、视频的回放(PlayBack),另一部分是音、视频的记录(Recorder)。

SGL:2D图像引擎。

SSL:即Secure Socket Layer,位于TCP/IP协议与各种应用层协议之间,为数据通信提供安全支持。

OpenGL ES:提供了对3D的支持。

界面管理工具(Surface Management):提供了管理显示子系统等功能。

SQLite:一个通用的嵌入式数据库。

WebKit:网络浏览器的核心。

FreeType:位图和矢量字体的功能。

在一般情况下,Android的各种库是以系统中间件的形式提供的,它们的显著特点是与移动设备平台的应用密切相关。另外,Android的运行环境主要是指 Dalvik(虚拟机)技术。Dalvik和一般的Java虚拟机(Java VM)是有区别的。

Java虚拟机:执行的是Java标准的字节码(Bytecode)。

ART+Dalvik:执行的是Dalvik可执行格式(.dex)中的执行文件。在执行的过程中,每一个应用程序即一个进程(Linux的一个Process)。二者最大的区别在于Java VM是以基于栈的虚拟机(Stack-based),而Dalvik是基于寄存器的虚拟机(Register-based)。显然,后者最大的好处在于可以根据硬件实现更大的优化,这更适合移动设备的特点。从Android 5.0版本开始,Android的默认运行环境为ART。ART的机制与Dalvik不同。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器转换为机器码,这会拖慢应用的运行效率,而在ART环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT,Ahead-Of-Time)。这样改进后,应用的启动(首次)和执行都会变得更加快速。

1.2.3 ApplicationFramework(应用程序框架)

在整个Android系统中,和应用开发最相关的是Application Framework,在这一层,Android为应用程序层的开发者提供了各种功能强大的APIs,这实际上是一个应用程序的框架。由于上层的应用程序是以Java构建的。在本层提供了程序中所需要的各种控件,例如,视图组件(Views)、列表(List)、栅格(Grid)、文本框(Text Box)、按钮(Button),甚至还有一个嵌入式的Web浏览器。

一个基本的Andoid应用程序可以利用应用程序框架中的以下5个部分。

Activity:活动。

Broadcast Intent Receiver:广播意图接收者。

Service:服务。

Content Provider:内容提供者。

Intent and Intent Filter:意图和意图过滤器。

1.2.4 顶层应用程序(Application)

Android的应用程序主要是用户界面(User Interface)方面的,本层通常使用Java语言编写,其中还包含各种被放置在“res”目录中的资源文件构成。Java程序和相关资源在经过编译后,会生成一个APK包。Android 本身提供了主屏幕(Home)、联系人(Contact)、电话(Phone)、浏览器(Browers)等众多的核心应用。同时应用程序的开发者还可以使用应用程序框架层的API实现自己的程序。这也是Android开源的巨大潜力的体现。

1.3 五大组件

在分析Android的源代码之前,很有必要先了解一下Android应用程序的核心组件功能。一个典型的Android应用程序通常由5个组件组成,这5个组件构成了Android的核心功能。在本节的内容中,将详细讲解这五大组件的基本知识。

1.3.1 Activity界面

Activities是这5个组件中最常用的一个组件。程序中Activity通常的表现形式是一个单独的界面(screen)。每个Aactivity都是一个单独的类,它扩展实现了Activity基础类。这个类显示为一个由Views 组成的用户界面,并响应事件。大多数程序有多个Activity。例如,一个文本信息程序有这么几个界面:显示联系人列表界面、写信息界面、查看信息界面或者设置界面等。每个界面都是一个Activity。切换到另一个界面就是载入一个新的Activity。某些情况下,一个Activity可能会给前一个Activity返回值,例如,一个让用户选择相片的Activity会把选择到的相片返回给其调用者。

打开一个新界面后,前一个界面就被暂停,并放入历史栈中(界面切换历史栈)。使用者可以回溯前面已经打开的存放在历史栈中的界面。也可以从历史栈中删除没有价值的界面。Android在历史栈中保留程序运行产生的所有界面:从第一个界面到最后一个。

1.3.2 Intent和IntentFilters切换

Android通过一个专门的Intent类来进行界面的切换。Intent描述了程序想做什么(Intent意为意图、目的、意向)。Intent类还有一个相关类IntentFilter。Intent是一个请求来做什么事情,Intent Filters则描述了一个Activity(或下文的Intent Receiver)能处理什么意图。显示某人联系信息的Activity使用了一个 IntentFilter,就是说它知道如何处理应用到此人数据的视图(View)操作。Activities在文件AndroidManifest.xml中使用Intent Filters。

通过解析Intents可以实现Activity的切换,可以使用startActivity(myIntent)启用新的Activity。系统会考察所有安装程序的Intent Filters,然后找到与myIntent匹配最好的Intent Filters所对应的Activity。这个新Activity能够接收Intent传来的消息,并因此被启用。解析Intents的过程发生在startActivity被实时调用时,这样做有如下两个好处。(1)Activities仅发出一个Intent请求,便能重用其他组件的功能。(2)Activities可以随时被替换为有等价IntentFilter的新Activity。

1.3.3 Service(服务)

Service是一个没有UI且长驻系统的代码,最常见的例子是媒体播放器从播放列表中播放歌曲。在媒体播放器程序中,可能有一个或多个Activities让用户选择播放的歌曲。然而在后台播放歌曲时无需Activity干涉,因为用户希望在音乐播放的同时能够切换到其他界面。既然这样,媒体播放器 Activity需要通过 Context.startService()启动一个 Service,这个 Service在后台运行以保持继续播放音乐。在媒体播放器被关闭之前,系统会保持音乐在后台播放。可以用Context.bindService()方法连接到一个Service上(如果Service未运行的话,连接后还会启动它),连接后就可以通过一个Service提供的接口与Service进行通话。对音乐Service来说,提供了暂停和重放等功能。

1.如何使用服务

在Android系统中,有如下两种使用Service的方法。(1)通过调用Context.startServece()启动服务,调用Context.stoptService()结束服务,startService()可以传递参数给Service。(2)通过调用 Context.bindService()启动,调用 Context.unbindService()结束,还可以通过ServiceConnection访问Service。二者可以混合使用,例如,可以先startServece()再unbindService()。

2.Service的生命周期

在使用 startService()方法启动服务后,即使调用 startService()的进程结束了,Service还仍然存在,一直到有进程调用stoptService()或Service自己灭亡(stopSelf())为止。

在 bindService()后,Service就和调用bindService()的进程同生共死,也就是说当调用bindService()的进程死了,那么它绑定的Service也要跟着被结束,当然期间也可以调用unbindService()让Service结束。

当混合使用上述两种方式时,例如,你用了startService(),我用了bindService(),那么只有你stoptService()了而且我也unbindService()了,这个Service才会被结束。

3.进程生命周期

在Android系统中,会尝试保留那些启动了的或者绑定了的服务进程,具体规则如下所示。(1)如果该服务正在进程的onCreate()、onStart()或者onDestroy()这些方法中执行时,那么主进程将会成为一个前台进程,以确保此代码不会被停止。(2)如果服务已经开始,那么它的主进程的重要性会低于所有的可见进程,但是会高于不可见进程。由于只有少数几个进程是用户可见的,所以只要不是内存特别少,该服务就不会停止。(3)如果有多个客户端绑定了服务,只要客户端中的一个对于用户是可见的,就可以认为该服务可见。

1.3.4 BroadcastReceiver发送广播

在Android系统中,Broadcast Receiver是一个广播接收器组件。广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码的,例如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播,例如,通知其他应用程序一些数据下载完成并处于可用状态。应用程序可以拥有任意数量的广播接收器以对所有它感兴趣的通知信息予以响应,所有的接收器均继承自BroadcastReceiver基类。

在Android系统中,广播接收器Broadcast Receiver没有用户界面。然而,它们可以启动一个Activity来响应它们收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力——闪动背灯、振动、播放声音等。一般来说是在状态栏上放一个持久的图标,用户可以打开它并获取消息。

Android中的广播事件有两种,一种是系统广播事件,例如:ACTION_BOOT_COMPLETED (系统启动完成后触发)、ACTION_TIME_CHANGED(系统时间改变时触发)、ACTION_BATTERY_LOW(电量低时触发)等。另一种是我们自定义的广播事件。

在Android系统中,广播事件的基本流程如下所示。(1)注册广播事件:注册方式有两种,一种是静态注册,即在AndroidManifest.xml文件中定义,注册的广播接收器必须要继承 BroadcastReceiver;另一种是动态注册,是在程序中使用Context.registerReceiver注册,注册的广播接收器相当于一个匿名类。两种方式都需要IntentFIlter。(2)发送广播事件:通过Context.sendBroadcast来发送,由Intent来传递注册时用到的Action。(3)接收广播事件:当发送的广播被接收器监听到后,会调用它的 onReceive()方法,并将包含消息的Intent对象传给它。onReceive中代码的执行时间不要超过5s,否则Android会弹出超时对话框。

1.3.5 用ContentProvider存储数据

在Android系统中,应用程序会把数据存放在一个SQLite数据库格式文件里,或者存放在其他有效设备里。如果想让其他程序能够使用我们程序中的数据,此时Content Provider就很有用了。Content Provider 是一个实现了一系列标准方法的类,这个类使得其他程序能存储、读取某种Content Provider可处理的数据。

1.4 进程和线程

Android系统中也有进程和线程,代表当前系统中正在运行的程序。当第一次运行某个组件的时候,Android 会启动一个进程。在默认情况下,所有的组件和程序运行在这个进程和线程中,也可以安排组件在其他的进程或者线程中运行。在本节的内容中,简要讲解Android进程和线程的基本知识。

1.4.1 什么是进程

组件运行的进程由manifest file控制的。组件的节点一般都包含一个process属性,例如节点。属性process可以设置组件运行的进程,可以配置组件在一个独立进程中运行,或者多个组件在同一个进程中运行,甚至可以多个程序在一个进程中运行,当然,前提是这些程序共享一个User ID并给定同样的权限。另外,节点也包含了process属性,用来设置程序中所有组件的默认进程。

当更加常用的进程无法获取足够内存时,Android会智能地关闭不常用的进程。当下次启动程序时会重新启动这些进程。当决定哪个进程需要被关闭时,Android 会考虑哪个对用户更加有用。例如Android会倾向于关闭一个长期不显示在界面的进程来支持一个经常显示在界面的进程。是否关闭一个进程决定于组件在进程中的状态。

1.4.2 什么是线程

当用户界面需要很快对用户进行响应,就需要将一些费时的操作,如网络连接、下载或者非常占用服务器时间的操作等放到其他线程。也就是说,即使为组件分配了不同的进程,有时候也需要再分配线程。

线程是通过Java的标准对象Thread来创建的,在Android中提供了如下管理线程的方法。(1)Looper在线程中运行一个消息循环。(2)Handler传递一个消息。(3)HandlerThread创建一个带有消息循环的线程。(4)Android让一个应用程序在单独的线程中,指导它创建自己的线程。(5)应用程序组件(Activity、Service、Broadcast Receiver)所有都在理想的主线程中实例化。(6)没有一个组件应该执行长时间或是阻塞操作(如网络呼叫或是计算循环)当被系统调用时,这将中断所有在该进程的其他组件。(7)可以创建一个新的线程来执行长期操作。

第2章 获取并编译Android源代码

在分析Android源代码之前,需要先获取Android系统的源代码,并在自己的机器上进行编译。在本章的内容中,将详细讲解获取并编译Android 5.0源代码的基本知识。另外,因为Android系统源代码的文件数量巨大,目录结构层次复杂,所以,将在本章对Android 5.0源代码的目录结构进行整体分析,并详细介绍从SDK中生成SDK的方法。

2.1 获取Android源代码

要想研究Android系统的源代码,需要先获取源代码。目前市面中的主流操作系统是Windows、Linux和Mac OS。因为Mac OS属于类Linux系统,所以本书将讲解在Windows系统和Linux系统中获取Android源代码的知识。

2.1.1 在Linux系统中获取Android源代码

北京时间2014年11月5日,Google在https://android.googlesource.com/上正式公布了Android 5.0的源代码,如图2-1所示。▲图2-1 Android 5.0的源代码分支

在Linux系统中,通常使用Ubuntu来下载和编译Android源代码。由于Android的源代码内容很多,Google采用了Git的版本控制工具,并对不同的模块设置不同的Git服务器,我们可以用repo自动化脚本来下载Android源代码。在Android官方站点 source.android.com/source/building.html中,提供了获取并编译Android源代码的具体过程,如图2-2所示。▲图2-2 Android官方提供的获取并编译源代码教程

在接下来的内容中,将详细讲解获取Android源代码的过程。(1)下载repo

在用户目录下,创建bin文件夹,用于存放repo,并把该路径设置到环境变量中去,命令如下: $ mkdir ~/bin $ PATH=~/bin:$PATH

下载repo的脚本,用于执行repo,命令如下: $ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo

设置可执行权限,命令如下: $ chmod a+x ~/bin/repo(2)初始化一个repo的客户端

在用户目录下,创建一个空目录,用于存放Android源代码,命令如下: $ mkdir AndroidCode $ cd AndroidCode

进入到AndroidCode目录,并运行repo下载源代码,下载主线分支的代码,主线分支包括最新修改的bug,以及并未正式发布的版本的最新源代码,命令如下: $ repo init -u https://android.googlesource.com/platform/manifest

下载其他分支正式发布的版本,可以通过添加-b参数来下载,命令如下: $ repo init -u https://android.googlesource.com/platform/manifest -b android-5.0_0_r1

例如可以使用如下命令来初始化最新的Android源代码: ./repo init -u https://android.googlesource.com/platform/manifest -b android-5.0_0_r1

在下载过程中会需要填写Name和E-mail,填写完毕之后,选择Y进行确认,最后提示repo初始化完成,这时可以开始同步Android源代码了,同步过程很漫长,需要耐心等待,执行下面命令开始同步代码: $ repo sync

经过上述步骤后,便开始下载并同步 Android源代码了,笔者的界面效果如图2-3所示。▲图2-3 正在下载源代码

因为网络方面的原因,可能执行“./repo init-u https://android.googlesource.com/platform/manifest-b android-5.0_0_r1”初始化命令会失败,提示一些类似网络连接失败的信息,此时不用理会,只需继续执行这个命令。如果出现多次失败提示,则可以尝试使用如下方法来解决。(1)使用如下命令删除Android 5.0文件中的缓存文件,然后重新执行初始化命令: rm -rf * -R(2)晚上、凌晨时下载,一般这个时候的网络环境容易下载Android源代码。

注意(1)在源代码下载过程中,在源代码下载目录看不到任何文件,打开“显示/隐藏”,会看到一个名为“.repo”的文件夹,这个文件夹是用来保存Android源代码的“临时文件”。(2)当文件最后下载接近完成时,会从“.repo”文件夹中导出Android源代码。(3)当Android 5.0源代码下载完成后,可以看到Android源代码下载目录中会有bionic、bootable、build、cts、dalvik等文件夹目录,这些就是Android的源代码。(4)如果不得不关闭电脑停止下载,那么可以在源代码下载的终端中按下Ctrl+C组合键或者Ctrl+Z组合键停止源代码的下载,这样不会造成源代码的丢失或损坏。

2.1.2 在Windows平台获取Android源代码

在Windows平台上获取Android源代码的方式和在Linux中获取原理相同,但是需要预先在Windows平台上面搭建一个Linux环境,此处需要用到cygwin工具。cygwin的作用是构建一套在Windows上的Linux模拟环境,下载cygwin工具的地址如下: http://cygwin.com/install.html

下载成功后会得到一个名为“setup.exe”可执行文件,通过此文件可以更新和下载最新的工具版本,具体流程如下所示。(1)启动cygwin,如图2-4所示。▲图2-4 启动cygwin(2)单击“下一步”按钮,选择第一个选项:从网络下载安装,如图2-5所示。▲图2-5 选择从网络下载安装(3)单击“下一步”按钮,选择安装根目录,如图2-6所示。▲图2-6 选择安装根目录(4)单击“下一步”按钮,设置网络代理。如果所在网络需要代理,则在这一步进行设置,如果不用代理,则选择直接下载,如图2-7所示。▲图2-7 设置网络代理(5)单击“下一步”按钮,选择下载站点。一般选择离我们比较近的站点,速度会比较快,如图2-8所示。▲图2-8 选择下载站点(6)单击“下一步”按钮,开始更新工具列表,如图2-9所示。▲图2-9 更新工具列表(7)单击“下一步”按钮,选择需要下载的工具包。在此需要依次下载curl、git、python这些工具,如图2-10所示。▲图2-10 依次下载工具

为了确保能够安装上述工具,一定要用鼠标双击图2-10中的那些项使其变为Install形式,如图2-11所示。▲图2-11 务必设置为Install形式(8)单击“下一步”按钮,经过漫长的等待过程,如图2-12所示。▲图2-12 下载进度条

如果下载安装成功会出现提示信息,单击“完成”按钮即完成安装。当安装好cygwin后,打开cygwin,会模拟出一个Linux的工作环境,然后按照Linux平台的源代码下载方法就可以下载Android源代码了。

建议读者在下载 Android 源代码时,严格按照官方提供的步骤进行,地址是:http://source.android.com/source/downloading.html,这一点对初学者来说尤为重要。另外,整个下载过程比较漫长,需要大家耐心等待。图2-13是下载Android源代码时的截图。▲图2-13 在Windows中用cygwin工具下载Android源代码

2.2 分析Android源代码结构

获得Android 5.0源代码后,源代码的全部工程分为以下3个部分。

Core Project:核心工程部分,这是建立Android系统的基础,被保存在根目录的各个文件夹中。

External Project:扩展工程部分,可以使其他开源项目具有扩展功能,被保存在“external”文件夹中。

Package:包部分,提供了Android的应用程序、内容提供者、输入法和服务,被保存在“package”文件夹中。

在本节的内容中,将详细讲解Android 5.0源代码的目录结构。▲图2-14 下载的Android 5.0源代码

2.2.1 总体结构

无论是Android 1.5还是Android 5.0,各个版本的源代码目录基本类似。在里面包含了原始Android的目标机代码、主机编译工具和仿真环境。解压缩下载的Android 5.0源代码包后,可以看到第一级目录有多个文件夹和一个Makefile文件,如图2-14所示。

如果是编译后的源代码目录,则会增加一个out文件夹,用来存放编译产生的文件。Android 5.0第一级别目录结构的具体说明如表2-1所示。表2-1 Android 5.0源代码的根目录

由此可见,通过对源代码中根目录的每个文件夹的功能的介绍,可以看出源代码按功能分类还是非常清晰的,可以分为系统代码、工具、文档、开发环境、虚拟机、配置脚本和编译脚本等类别。并且也可以看出涉及的内容比较庞大和复杂,源代码分析工作需要多方面的理论和实践知识。

2.2.2 应用程序部分

应用程序主要是UI界面的实现,广大开发者基于SDK上开发的一个个独立的APK包,都是属于应用程序这一层的,应用程序在Android系统中处于最上层的位置。源代码结构中的packages目录用来实现系统的应用程序,packages的目录结构如下所示。 packages / ├── apps //应用程序库 │ ├── BasicSmsReceiver //基础短信接收 │ ├── Bluetooth //蓝牙 │ ├── Browser //浏览器 │ ├── Calculator //计算器 │ ├── Calendar //日历 │ ├── Camera //照相机 │ ├── CellBroadcastReceiver //单元广播接收 │ ├── CertInstaller //被调用的包,在Android中安装数字签名 │ ├── Contacts //联系人 │ ├── DeskClock //桌面时钟 │ ├── Email //电子邮件 │ ├── Exchange //Exchange服务 │ ├── Gallery //图库 │ ├── Gallery2 //图库2 │ ├── HTMLViewer //HTML查看器 │ ├── KeyChain //密码管理 │ ├── Launcher2 //启动器2 │ ├── Mms //彩信 │ ├── Music //音乐 │ ├── MusicFX //音频增强 │ ├── Nfc //近场通信 │ ├── PackageInstaller //包安装器 │ ├── Phone //电话 │ ├── Protips //主屏幕提示 │ ├── Provision //引导设置 │ ├── QuickSearchBox //快速搜索框 │ ├── Settings //设置 │ ├── SoundRecorder //录音机 │ ├── SpareParts //系统设置 │ ├── SpeechRecorder //录音程序 │ ├── Stk //sim卡相关 │ ├── Tag //标签 │ ├── VideoEditor //视频编辑 │ └── VoiceDialer //语音编号 ├── experimental //非官方的应用程序 │ ├── BugReportSender //Bug的报告程序 │ ├── Bummer │ ├── CameraPreviewTest //照相机预览测试程序 │ ├── DreamTheater │ ├── ExampleImsFramework │ ├── LoaderApp │ ├── NotificationLog │ ├── NotificationShowcase │ ├── procstatlog │ ├── RpcPerformance │ └── StrictModeTest ├── inputmethods //输入法 │ ├── LatinIME //拉丁文输入法 │ ├── OpenWnn //OpenWnn输入法 │ └── PinyinIME //拼音输入法 ├── providers //提供器 │ ├── ApplicationsProvider //应用程序提供器,提供应用程序所需的界面 │ ├── CalendarProvider //日历提供器 │ ├── ContactsProvider //联系人提供器 │ ├── DownloadProvider //下载管理提供器 │ ├── DrmProvider //数据库相关 │ ├── GoogleContactsProvider //Google联系人提供器 │ ├── MediaProvider //媒体提供器 │ ├── TelephonyProvider //彩信提供器 │ └── UserDictionaryProvider //用户字典提供器 ├── screensavers //屏幕保护 │ ├── Basic //基本屏幕保护 │ ├── PhotoTable //照片方格 │ ├── WebView //网页 └── wallpapers //墙纸 ├── Basic //系统内置墙纸 ├── Galaxy4 //S4内置墙纸 ├── HoloSpiral //手枪皮套墙纸 ├── LivePicker ├── MagicSmoke ├── MusicVisualization ├── NoiseField └── PhaseBeam

通过上面的目录结构可以看出,package目录主要存放的是与Android系统应用层相关的内容,包括应用程序相关的包或者资源文件,其中包括系统自带的应用程序,及第三方开发的应用程序,还有屏幕保护和墙纸等应用,所以源代码中package目录对应着系统的应用层。

2.2.3 应用程序框架部分

应用程序框架是Android系统中的核心部分,也就是SDK部分,它会提供接口给应用程序使用,同时应用程序框架又会和系统服务、系统程序库、硬件抽象层有关联,所以其作用十分重大,应用程序框架的实现代码大部分都在/frameworks/base和/framwworks/av目录下,/frameworks/base的目录结构如下所示。 frameworks/base ├── api //全是XML文件,定义了API ├── cmds //Android中的重要命令(am、app_proce等) ├── core //核心库 ├── data //声音字体等数据文件 ├── docs //文档 ├── drm //数字版权管理 ├── graphics //图形图像 ├── icu4j //用于解决国际化问题 ├── include //头文件 ├── keystore //数字签名证书相关 ├── libs //库 ├── location //地理位置 ├── media //多媒体 ├── native //本地库 ├── nfc-extras //NFC相关 ├── obex //蓝牙传输 ├── opengl //opengl相关 ├── packages //设置、TTS、VPN程序 ├── policy //锁屏界面相关 ├── sax //XML解析器 ├── services //Android的服务 ├── telephony //电话相关 ├── test-runner //测试相关 ├── tests //测试相关 ├── tools //工具 ├── voip //可视通话 └── wifi //无线网络

以上这些文件夹包含了应用程序框架层的大部分代码,正是这些目录下的文件构成了Android的应用程序框架层,暴露出接口给应用程序调用,同时衔接系统程序库和硬件抽象层,形成一个由上至下的调用过程。在/frameworks/base目录下也涉及系统服务,程序库中的一些代码,我们将在后面的两个小节中再详细分析。

2.2.4 系统服务部分

在2.2.2中介绍了应用程序框架层的内容,了解到大部分的实现代码保存在“/frameworks/base”目录下。其实在这个目录中还有一个名为“service”的目录,里面的代码是用于实现 Android 系统服务的。接下来将详细介绍service目录下的内容,其目录结构如下所示。 frameworks/base/services ├── common_time //时间、日期相关的服务 ├── input //输入系统服务 ├── java //其他重要服务的Java层 ├── jni //其他重要服务的JNI层 └── tests //测试相关

其中java和jni两个目录分别是一些其他的服务的Java层和JNI层实现,Java目录下更详细的目录结构以及其他Android系统服务的说明如下所示。 frameworks/base/services/java/com/android/server ├── accessibility ├── am ├── connectivity ├── display ├── dreams ├── drm ├── input ├── location ├── net ├── pm ├── power ├── updates ├── usb ├── wm ├── AlarmManagerService.java //闹钟服务 ├── AppWidgetService.java //应用程序小工具服务 ├── AppWidgetServiceImpl.java ├── AttributeCache.java ├── BackupManagerService.java //备份服务 ├── BatteryService.java //电池相关服务 ├── BluetoothManagerService.java //蓝牙 ├── BootReceiver.java ├── BrickReceiver.java ├── CertBlacklister.java ├── ClipboardService.java ├── CommonTimeManagementService.java //时间管理服务 ├── ConnectivityService.java ├── CountryDetectorService.java ├── DevicePolicyManagerService.java ├── DeviceStorageMonitorService.java //设备存储器监听服务 ├── DiskStatsService.java //磁盘状态服务 ├── DockObserver.java //底座监视服务 ├── DropBoxManagerService.java ├── EntropyMixer.java ├── EventLogTags.logtags ├── INativeDaemonConnectorCallbacks.java ├── InputMethodManagerService.java //输入法管理服务 ├── IntentResolver.java ├── IntentResolverOld.java ├── LightsService.java ├── LocationManagerService.java //地理位置服务 ├── MasterClearReceiver.java ├── MountService.java //挂载服务 ├── NativeDaemonConnector.java ├── NativeDaemonConnectorException.java ├── NativeDaemonEvent.java ├── NetworkManagementService.java //网络管理服务 ├── NetworkTimeUpdateService.java ├── NotificationManagerService.java //通知服务 ├── NsdService.java ├── PackageManagerBackupAgent.java ├── PreferredComponent.java ├── ProcessMap.java ├── RandomBlock.java ├── RecognitionManagerService.java ├── SamplingProfilerService.java ├── SerialService.java //NFC相关 ├── ServiceWatcher.java ├── ShutdownActivity.java ├── StatusBarManagerService.java //状态栏管理服务 ├── SystemBackupAgent.java ├── SystemServer.java ├── TelephonyRegistry.java ├── TextServicesManagerService.java ├── ThrottleService.java ├── TwilightCalculator.java ├── TwilightService.java ├── UiModeManagerService.java ├── UpdateLockService.java //锁屏更新服务 ├── VibratorService.java //振动服务 ├── WallpaperManagerService.java //壁纸服务 ├── Watchdog.java //看门狗 ├── WifiService.java //无线网络服务 └── WiredAccessoryManager.java //无线设备管理服务

从上面的文件夹和文件可以看出,Android中涉及的服务种类非常多,包括界面、网络、电话等核心模块基本上都有其专属的服务,这些是属于系统级别的服务,这些系统服务一般都会在Android系统启动的时候加载,在系统关闭的时候结束,受到系统的管理,应用程序并没有权力去打开或者关闭,它们会随着系统的运行一直在后台运行,供应用程序和其他的组件使用。

另外,在frameworks/av/下面也有一个services目录,这个目录下存放的是音频和照相机的服务的实现代码,目录结构如下所示。 frameworks/av/services ├── audioflinger //音频管理服务 └── camera //照相机的管理服务

这个av/services目录下的文件主要是用来支持Android系统中的音频和照相机服务的,这是两个非常重要的系统服务,开发应用程序时会经常依赖这两个服务。

2.2.5 系统程序库部分

Android的系统程序库类型非常多,功能也非常强大,正是有了这些程序库,Android系统才能运行多种多样的应用程序。在接下来的内容中,笔者挑了一些很常用也是很重要的系统程序库来分析它们在源代码中所处的位置。(1)系统C库

Android系统采用的是一个从BSD继承而来的标准的系统函数库bionic,在源代码根目录下有这个文件夹,其目录结构如下所示。 bionic/ ├── libc //C库 ├── libdl //动态链接库相关 ├── libm //数学库 ├── libstdc++ //C++实现库 ├── libthread_db //线程库 ├── linker //连接器相关 └── test //测试相关

试读结束[说明:试读内容隐藏了图片]

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载