Android开发精要(txt+pdf+epub+mobi电子书下载)


发布时间:2020-09-15 03:45:07

点击下载

作者:范怀宇

出版社:机械工业出版社

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

Android开发精要

Android开发精要试读:

前言

为什么要写这本书

一直觉得我和Android还是蛮有缘分的,从Android发布第一个版本的SDK开始,我就一直在“摸着石头”写各种Android应用,了解一切与Android有关的事情,直至今日。还记得刚开始接触Android时,由于缺少相关的学习资料或书籍,入门都是一件非常困难的事情,只能靠自己不断地翻看SDK文档、尝试各种代码实现来揣摩如何开发Android应用,因而走过很多弯路,几乎犯过所有可能出现的错误,深感写好Android程序并不是一件很容易的事情。

如今有大量的开发者开始从事Android开发,幸运的是很多前辈写了大量关于Android开发的书籍,其中包括很多非常优秀的书籍,能帮助Android开发者更快速地学习Android开发,使他们不用再重复我当年初学时的痛苦。

但从我在工作中接触到的Android开发者来看,虽然学会如何编写Android应用不再是难事,但他们依旧困扰于如何写出地道的、贴近Android设计理念的、更加高效和运行可靠的Android应用。虽然已经有很多功力深厚的书籍详细剖析过Android底层实现的方方面面,能帮助开发者把Android应用写得更出色,但正是由于这类书中包含了大量底层实现细节,因此使得开发者学习成本较高,难于从中快速获取期望的内容,痛感“远水解不了近渴”。

因此,我萌生了写这本书的念头,期望从我的开发经验和繁杂的Android源代码中,抽取出Android开发的“精华”和“要点”,这些“精要”剥离了很多琐碎的实现细节,进行了更多的概括和总结。这一方面能够帮助开发者更深入理解Android的应用开发,从学会Android进阶到理解Android;另一方面又使他们不会被太多细节所牵绊,能够更快速地学习和掌握所需内容。

本书主要内容

本书将所有内容整理成四个部分共13章。

第一部分帮助读者重新认识Android,并从各个角度来介绍一些Android的核心理念和学习方法,包含前两章内容。第1章从多个方面介绍和阐述了对Android架构的理解,只有真正理解Android的设计理念和思想才能够更快地掌握Android开发。第2章介绍了如何获取、编译和阅读Android源代码,对于愿意投入更多时间学习Android的开发者来说,源代码无疑是最好的学习资料。

第二部分深入阐述了Android最核心的组件机制,包含4章内容。第3章从整体上阐述了Android组件机制的设计理念和重要特征,详细介绍了4大组件的特点和使用方式。第4章从设计和源代码出发,讲解了Intent对象和Android的意图机制,旨在帮助开发者理解Android是如何将来自不同应用、不同进程的组件整合在一起工作的。第5章介绍了Android各个组件的生命周期,包括每个组件的进程模型、线程模型,以及编程时需要把控的一些“要点”。第6章从实际开发的角度出发,详细介绍了组件间数据传递的解决方案,以及这些解决方案的优缺点和使用场景。

接下来的第三部分,转换到了另一个核心话题,即Android的交互界面开发,包括两章内容。第7章讲解了Android的控件框架,结合实际的项目,对重要控件的实现和使用逐一进行了分析与讲解,其中包含了最新的Android 4.0界面开发的一些实践“精华”。第8章继续介绍了Android的资源体系,详细剖析了Android底层对资源的处理,并结合具体的应用实现介绍了如何正确地配置资源和构建交互界面。

剩下的章节是第四部分,其内容涵盖了Android的各个核心模块,对每个模块的实现机制都做了分析,并结合具体的工程实践针对使用模块时最容易遇到的问题给出了解决方案。第9章介绍了Android的数据存储结构,以及不同的数据存储模式的使用要点,包括基于文件、基于设置文件(Preference)、基于数据库、基于云端等多种模式。第10章介绍了Android丰富多彩的网络连接方式,着重介绍了开发时常见问题的解决,范围不仅涵盖了传统的HTTP连接、蓝牙传输,还包括最新的近场通信(NFC)和基于WiFi的P2P连接等。第11章讲解的是Android的地理信息服务,不仅包括Android的定位服务、地址服务和地图服务的框架实现,还特别针对定位时会遇到的各个问题给出了解决方案。第12章围绕Android的多媒体信息处理展开,具体包括了图像、音频、视频和相机的实现和使用,内存占用量大是多媒体处理中最常见的问题,该章结合对一些系统应用的剖析,总结了一些常用的解决策略。第13章涵盖内容比较多,主要介绍的是Android中比较有特色的一些模块,包括短信和通话的处理、联系人的使用、通知机制(Notification)、桌面小工具(App Widget)的开发等内容,着重介绍的是一些比较有特色的实现细节,以帮助开发者写出更为“地道”的Android应用。

本书特色

本书最大的特色在于对底层实现机制的总结和整理,以及结合项目实践经验对开发中常遇到的核心问题给出具体的解决策略。

对于底层实现机制的整理,可视为Android开发的“要点”,每个开发者都需要理解和掌握这些内容,才能在开发时“下笔如有神”。为了能够更好地传达这些要点,本书中不会出现大段的底层实现代码,而是把所有的实现机制和策略,整理成文字和图表进行总结解析,以帮助读者更轻松地学习和理解。

而对于实际开发问题的解决策略,可看做是Android开发中的“精华”部分。本书从系统应用和一些优秀开源项目中整理出常见问题的解决策略,并结合个人实践经验分析不同解决策略的思想和适用场景,不仅能够授读者以解决问题之“鱼”,更能够授其分析问题之“渔”。

本书面向的读者

我期望所有的Android应用开发者都能够从本书中获益。对于Android初学者而言,可以着重阅读本书对Android设计思想、组件机制、UI框架的介绍,增强对Android底层机制的理解,这对于日后开发更高效、可靠的Android应用,必将有所裨益。

而对于具有丰富Android开发经验、对Android基础框架有很深认识的资深开发者而言,可以在本书中寻找针对具体问题给出的一些解决策略,相信这些策略会对解决开发中的实际问题有所帮助。

如何阅读本书

从本书的结构来看,前三部分包含的内容对于大部分开发者都适用,可以逐节进行阅读;而第四部分包含的内容则可以结合具体问题有选择地进行阅读。

本书在介绍内容的过程中,会涉及Android中的具体Java类,在首次提及时会使用完整的类名进行描述,如android.app.Activity,而在之后再次提及时则会略去全部的包信息,仅使用类名,如Activity,以节约篇幅便于阅读。

与之类似,本书会将一些英文的专有名词翻译成中文,在首次提及时会使用中英文对照的方式,如界面组件(Activity),而再次涉及时则会直接使用中文名称,如界面组件。

本书几乎没有完整的代码实例(具体的实例来源会给出对应的链接或描述),只有从中截取并改良过的代码片段,其描述风格如下:

//这是一段示例代码,在代码的重要位置,会用注释给出解释

String hello="Hello,";//重要的变量、函数会用粗体表示

String user_name=GetUserName();//一些虚拟的函数、变量,会用斜体表示

…//一些略去的实现细节,会用省略号表示

此外,本书会穿插一些小贴士,提供相关联的知识内容,小贴士的格式形如:

小贴士 这是一则小贴士,所谓小贴士,就是对相关内容进行扩展介绍,或者是加入一些个人的理解。

资源及勘误

由于个人能力的局限,虽已竭尽所能,但在本书中对于一些问题的理解难免会有所纰漏,给出的一些解决方案也可能会有缺陷,敬请读者海涵。如在阅读过程中发现问题或者有所疑问需要讨论,可发邮[1][2]件至我的邮箱,所有关于本书内容的勘误会在个人博客上不断更新。

[1]作者邮箱:duguguiyu@gmail.com。

[2]作者博客:http://flyvenus.net。

致谢

两年前的一天,本书的策划编辑杨福川在我的博客上看到了本书最雏形的一些文字,便极力邀请并最终促成了这本书。感谢福川在两年多的时间里一直鼓励着我,容忍着我无限期的“跳票”,帮我整理思路继续前行,感谢他和他的同事白宇、王晓菲、曾珊帮我打磨每一行文字,整理每一张图片,没有他们的专业和坚持就不会有本书的最终完稿,感谢你们,感谢机械工业出版社。[1]

也要感谢我的前东家网易有道,是它给我机会来开发诸如有道词典这样拥有大量用户的Android应用,在这个过程中我积累了大量的实践经验,这是我能够完成本书的技术基础。[2]

更要感谢豌豆实验室和所有的豌豆们,这是我正为之奋斗的公司和一起战斗的同事们,在这里我不仅开拓了技术视野,了解了更丰富的Android技术,更重要的是,让我体会到了什么是为了理想而共同奋斗,这是鞭策我不断前进的动力。

还要感谢那些和我一起写Android代码的朋友们,徐岚、阳光元、王健飞、吴淼伟…那些我写下你们解掉的Bug,都让我从中学到了新的知识。

当然,一定要感谢我的家人,我的父母每周都会问我:“书写得怎么样了?早点休息,别太辛苦!”我想说,有你们的支持,我永远不会辛苦。感谢我的妻子张佳,本来我想拿着这本书作为我们的结婚礼物,却未曾想到,待到出版时我们已然是老夫老妻了,两年间你一直鼓励我、帮助我完成此书,感谢有你,一直陪伴在你身边,是我能为你做的。

最后,感谢所有即将阅读此书的朋友们,如果有人能从此书获益,将是我莫大的欣慰。

范怀宇

[1]网易有道是网易旗下搜索引擎,网址是:http://www.youdao.com。

[2]豌豆实验室是创新工场早期孵化的创业公司,出品了Android手机助手豌豆荚,网站是:http://www.wandoujia.com。第1章Android的系统架构1.1 Android系统架构概况1.2 Android的核心功能模块1.3 Android的架构特征和设计思想1.4 小结在Android开发中,迫于工程进度压力,开发者很多时候都是以项目为导向进行学习,项目需要什么就了解什么,在实践中不断探索。这是一条捷径,但充满着潜在的危险,因为项目中用到的知识往往是片面的、不系统的,这使得开发者对Android难以有全面的认知。这就好比在陌生的沙漠中行走,如果只关注周边景致,一不小心就会迷失方向,浪费了时间和精力。因此,在进入沙漠之前,需要带上定位仪。在进行Android开发之前,有必要先学习一下Android的整体架构,了解它的设计思想及各个核心模块。有了这些知识储备,再去看实际的项目,就能更清楚地理解为什么要这样设计。即使在开发中遭遇难题,也可以凭借对Android的了解,尽快找出哪些模块和设计能够帮助解决该问题。更重要的,只有对Android的设计和功能有了深入和全面的理解,才能够设计出更加卓越的产品架构,而不再是照葫芦画瓢似的开发。磨刀不误砍柴工,本章将介绍Android的系统架构,具体内容包括:❑Android的整体架构和特征❑Android的主要功能模块及其特点❑Android的设计思想1.1 Android系统架构概况[1]

图1-1是Android的架构图,图中按照功能结构及面向人群进行划分,可以看出Android分成三个部分:

❑应用部分:包含在Android设备上运行的所有应用,它们是Android系统中直接面向用户的部分。

❑核心部分:Android系统中核心的功能实现,包括应用框架、核心类库等,每个Android应用的开发者,都是在此基础上进行应用开发的。

❑:主要指Android寄宿的Linux操作系统及相关驱动。通常来说,只有硬件厂商和从事Android移植的开发者,才会基于此来进行开发。

除了上述划分方式以外,从系统实际的架构模型来看,Android则可以分成以下几个层次:

❑应用层

❑框架层

❑运行时

❑核心类库

❑硬件抽象层

❑Linux内核图 1-1 Android系统架构图

本节的后续内容将针对以上各层逐一进行分析。1.1.1 应用层

对于普通的用户而言,只能通过具体的应用来判断移动平台的优劣。即便一个移动平台具有最华丽的技术,但是如果不能给用户提供最得心应手的应用,顶多也只能赢得无冕之王的名头,而无法抓住用户的心,赢得市场的认可。

Android应用层由运行在Android设备上的所有应用共同构成,它不仅包括通话、短信、联系人等系统应用(随Android系统一起预装在移动设备上),还包括其他后续安装到设备中的第三方应用。

第三方应用都是基于Android提供的SDK(Software Development Kit)进行开发的,并受到SDK接口的约束。而预装在设备中的系统应用,则可以调用整个框架层的接口和模块,其中的很多接口在SDK中是隐藏的,因此,系统应用具有比第三方应用更多的权利。

Android的应用都是基于Java语言来开发的,但在很多应用(尤其是游戏)中,需要进行大规模的运算和图形处理,以及使用开源C/C++类库。通过Java来实现,可能会有执行效率过低和移植成本过高等问题。因此在Android开发中,开发者可以使用C/C++来实现底层模块,并添加JNI(Java Native Interface)接口与上层Java实现进行交互,然后利用Android提供的交叉编译工具生成类库并添加到应用中。

为了让应用开发者能够绕过框架层,直接使用Android系统的特定类库,Android还提供了NDK(Native Development Kit),它由C/C++的一些接口构成,开发者可以通过它更高效地调用特定的系统功能。

但在Android上,开发者通常只能使用C/C++编写功能类库,而不是整个应用。这是因为,诸如界面绘制、进程调度等核心机制是部署在框架层并通过Java来实现的,应用只有按照它们规定的模式去编写特定的Java模块和配置信息,才能够被识别、加载和执行。

小贴士 从Android 2.3(API 9)开始,新增了android.app.NativeActivity类,它是通过调用预定义的JNI接口来实现的。开发者可以基于NDK,通过C/C++语言来实现具体功能。这就意味着,开发者仅通过C/C++语言就能实现整个应用。这对于游戏开发者而言是一大喜讯,但由于控件在Android中并没有Native的实现,普通的应用开发者通常还是需要通过Java来实现上层界面。

[1]参考自SDK文档:http://androidappdocs.appspot.com/guide/basics/what-is-android.html。1.1.2 框架层

框架层是Android系统中最核心的部分,它集中体现了Android系统的设计思想。在Android之前,有很多基于Linux内核打造的移动平台。作为超越前辈的成功范例,框架层的设计正是Android脱颖而出的关键所在。

框架层由多个系统服务(System Service)共同组成,包括组件管理服务、窗口管理服务、地理信息服务、电源管理服务、通话管理服务,等等。所有服务都寄宿在系统核心进程(System Core Process)中,在运行时,每个服务都占据一个独立的线程,彼此通过进程间的通信机制(Inter-Process Communication, IPC)发送消息和传输数据。

应用层中的应用,时刻都在与这些系统服务打交道。每一次构造窗口、处理用户交互事件、绘制界面、获得当前地理信息、了解设备信息等操作,都是在各个系统服务的支持下实现的。

而对于开发者而言,框架层最直观的体现就是SDK,它通过一系列的Java功能模块,来实现应用所需的功能。SDK的设计决定了上层应用的开发模式、开发效率及能够实现的功能范畴。因此,对于开发者而言,关注SDK的变迁是一件很有必要的事情,SDK每个新版本的诞生,都意味着一些老的接口会被调整或抛弃,另一些新的接口和功能火热出炉。开发者不但要查看和关注那些被修改的接口,来检查应用的兼容性,并采取相应的策略去适应这些变化,更重要的是,开发者还要追踪新提供的接口,寻找改进应用的机会,甚至是寻求开发新应用的可能。

从系统设计的角度来看,Android期望框架层是所有应用运行的核心,参与到应用层的每一次操作中,并进行全局统筹。Android应用的最大特征是基于组件的设计方式。每个应用都由若干个组件构成,组件和组件之间并不会建立通信信道,而是通过框架层的系统服务,集中地调度和传递消息。这样的设计方式相当于增加了一个中间层,该层了解所有组件的状况,可以更智能地进行协调,从而提升了整个系统的灵活性。1.1.3 运行时

和所有的Java程序运行平台一样,为了实现Java程序在运行阶段的二次编译,Android为它们提供了运行时(Runtime)的支撑。

Android的运行时由Java核心类库和Java虚拟机Dalvik共同构成。[1]Java核心类库涵盖了Android框架层和应用层所要用到的基础Java库,包括Java对象库、文件管理库、网络通信库,等等。

Dalvik是为Android量身打造的Java虚拟机,负责动态解析执行应用、分配空间、管理对象生命周期等工作。如果说框架层是整个Android的大脑,决定了Android应用的设计特征,那么,Dalvik就是Android的心脏,为Android的应用提供动力,决定它们的执行效率。

与为低端移动设备而设计的J2ME虚拟机不同,Dalvik是专门为高端设备而优化设计的。它没有采用基于栈的虚拟机架构,而是采取了基于寄存器的虚拟机架构设计。通常来说,基于栈的虚拟机对硬件的依赖程度小、生成的应用更节约空间,可以适配更多的低端设备;而基于寄存器的虚拟机,对硬件的门槛会更高一些,编译出的应用可能会耗费稍多的存储空间,但它的执行效率更高,更能够发挥高端硬件(主要指处理器)的能力。

Dalvik没有沿用传统的Java二进制码(Java Bytecode)作为其一次编译的中间文件,而是应用了新的二进制码格式文件.dex。在Android应用的编译过程中,它会先生成若干个.class文件,然后统一转换成一个.dex文件。在转换过程中,Android会对部分.class文件中[2]的指令做转义,使用Dalvik特有的指令集OpCodes来替换,以提高执行效率。同时,.dex会整合多个.class文件中的重复信息,并对冗余部分做全局的优化和调整,合并重复的常量定义,以节约常量池耗费的空间。这使得最终得到的.dex文件通常会比将.class文件压缩打包得出的.jar文件更精简。

为了提升Android应用的执行效率,从垃圾回收器(Garbage Collection, GC)到编译器,Dalvik一直在各个方面进行优化。经常可以听到这样的消息:“新版本的Android系统,比上一个版本的效率高了x倍。”这大都是改善Dalvik的效果。在Android 2.2中,Dalvik引入了对JIT(Just-in-time)编译的支持,将上层应用的执行效率提升了2~4倍,开启了Android发展的新篇章。

由于对于大部分应用开发者而言,无须了解Android运行时的具体细节,因此,本书后续将不会详细介绍Android运行时的相关内[3]容,有兴趣的读者,可以另行查阅相关资料和源代码。

[1]它的主要实现来自于开源项目Apache Harmony,其官方主页是:http://harmony.apache.org。

[2]参见如下链接:http://developer.android.comreference/dalvik/bytecode/Opcodes.html。

[3]维基百科是学习Dalvik的一个不错途径:http://en.wikipedia.org/wiki/Dalvik_(software)。1.1.4 核心类库

对于框架层而言,核心类库就是它的“贤内助”。每一次Android系统升级,能看到的都是框架层SDK的变迁,增加了新的功能,提供了新的接口。而在这些新功能的背后,核心类库都是居功至伟。

核心类库由一系列的二进制动态库共同构成,通常使用C/C++进行开发。与框架层的系统服务相比,核心类库不能够独立运行于线程中,而需要被系统服务加载到其进程空间里,通过类库提供的JNI接口进行调用。

核心类库的来源主要有两种,一种是系统原生类库,Android为了提高框架层的执行效率,使用C/C++来实现它的一些性能关键模块,如:资源文件管理模块、基础算法库,等等。而另一种则是第三方类库,大部分都是对优秀开源项目的移植,它们是Android能够提供丰富功能的重要保障,如:Android的多媒体处理,依赖于开源项[1][2]目OpenCORE的支持;浏览器控件的核心实现,是从Webkit 移植[3]而来;而数据库功能,则是得益于Sqlite。Android会为所有移植而来第三方类库封装一层JNI接口,以供框架层调用。

为了帮助游戏和图形图像处理等领域的开发者搭建更高效的应用,Android将数学函数库、OpenGL库等核心类库以NDK的形式提供给开发者,开发者可以基于NDK更高效地构建算法,进行图形图像绘制。从实践的角度看,只要能获取到底层类库的头文件信息,开发者就可以逾越NDK的界限,用其他核心类库的接口进行开发。但这样做的危险之处在于兼容性差,Android在版本变迁时,可能会替换或修改一些类库接口或实现,这就会导致依赖于这些类库的应用无法运行。而NDK提供的都是稳定的类库实现,不会再做修改,以保证使用NDK的应用具有向上的兼容性。

[1]OpenCORE的官方主页是:http://www.opencore.net/。

[2]Webkit的官方主页是:http://www.webkit.org/。

[3]Sqlite的官方主页是:http://www.sqlite.org/。1.1.5 硬件抽象层和Linux内核

Android系统并不是从零开始设计的,而是搭建在Linux内核之上。狭义的Android系统,主要指的是Linux内核以上的各层,从运行的角度来看,它们只是运行在Linux系统上的一些进程,并不是完整的系统,离开了Linux的支撑,就像鱼儿离开了水一样,无法运行。

Linux之于Android最大的价值,便是其强大的可移植性。Linux可以运行在各式各样的芯片架构和硬件环境下,而依托于它的Android系统,也便有了强大的可移植性。同时,Linux像一座桥梁,将Android的上层实现与底层硬件连接起来,使它们可以不必直接耦合,因此,降低了移植的难度。

而硬件抽象层(Hardware Abstract Layer, HAL),是Android为厂商定义的一套接口标准,它为框架层提供接口支持,厂商需要根据定[1]义的接口实现相应功能。

[1]移植Android需要实现的硬件抽象层头文件,请参见:http://source.android.com/porting/index.html。1.2 Android的核心功能模块

上节从层次结构的角度出发,对Android做了介绍。而本节将换一个角度,从具体的功能模块上去认识Android,介绍Android具体都能做些什么及能做到什么程度。了解这些功能模块的概况,就像看Android的“个人简历”一样,可以帮助我们对它的能力有整体上的认识,进而在应用开发之前可以更好地评估技术上的可能性和风险性。

本节将依次介绍Android的各个重要的功能模块,而本书的后续章节会对开发者需要关注的功能点进行更为详尽的剖析。1.2.1 界面框架

每个Android开发者都会关心Android到底能够打造怎样的用户界面(User Interface, UI)。Android界面框架中最有特色的部分是资源(Resource)和布局(Layout)体系,通过完善的控件库和简明的接口设计,开发者可以尽快搭建自己需要的界面。

Android的每个交互界面都由一棵控件树构成。控件树中的控件(Widget)对象皆派生自android.view.View类,而其中非子节点的控件都派生自android.view.ViewGroup类,可称之为容器控件。控件树中的控件都受其父控件的管理,父控件会负责子控件的丈量和绘制,并向子控件分发交互事件。

Android的每个控件都有焦点、可视性、可用性、标识、背景等诸多控件属性。而为了获取用户与控件的交互事件(UI Events),可以为控件添加各种交互事件监听对象(Event Listener),它的设计采用了观察者模式。

Android中最有特色的控件,当属布局控件(Layout Widget)。这是一种自容器控件,其主要任务并不是展示自己,而是按不同的方式排列其中的子控件。比如,线性布局控件(android.widget.LinearLayout)会将其中的子控件按水平或竖直方向依次排列,而表格布局控件(android.widget.TableLayout)则会依照构造的行列结构摆放控件。

为了帮助开发者逃离界面开发的“泥沼”,Android部署了完整的应用资源(Application Resources)体系。所谓完整,就是Android将所有和界面相关的元素,比如界面布局、文字信息、尺寸信息、颜色和图像等,都从代码中剥离出来,用应用资源来进行描述。Android的应用资源由资源目录、XML资源文件和数据资源文件共同构成。XML文件比逻辑化的代码更适合描述界面这样的结构化概念,而Android用特殊的资源目录结构来针对移动设备的屏幕特征、语言环境和外部设备等特征部署资源文件,以此来解决设备的兼容性问题。

对于开发者而言,高效地构架产品所需的界面效果是最重要的一件事情。所谓高效,包括开发效率要高,同时也包括界面交互时更流畅,加载速度更快。本书的第7章和第8章会对Android的界面框架进行详细的介绍,其中,会结合一些优秀的界面实现来实际探索如何构建足够高效的交互界面。1.2.2 数据存储

对于很多应用而言,大到复杂的结构化数据,小到简单的设置信息,都有数据存储的需求。广义上看,应用数据存储有两种方式:一种是将数据存放在本地存储设备中;而另一种则是通过网络,将数据存储在远端服务器中,也就是常说的“云存储”。

Android本地数据存储的最大特点是数据的私有化。每个应用的配置信息和数据库文件等数据,都是其私有的,其他应用没有权限进行读写,从而保证了应用数据的安全性。而对于如何将其数据共享给其他应用,一个策略是构造一个数据源组件(Content Provider),其他应用的组件可以通过数据源组件的接口访问它所提供的数据;而另一个常用的策略是将数据放入扩展存储设备(通常是SD卡等扩展存储卡)中,在该存储设备中的数据,可以被所有应用共同访问。比如,Android的多媒体数据文件通常存储在扩展存储设备中,以便各个图像应用、音乐播放应用等读写。

Android对本地数据的存储,可以有多种文件格式,比如普通数据文件、设置文件和数据库,等等。设置文件(Preferences)是专门针对存储应用设置信息而设计的,它依照键值对的形式进行保存,Android从界面到存储都做了完整的支持。而Android的数据库依靠Sqlite的支持,在android.database包中提供了更为便捷的读写类库支持,开发者可以使用SQL语言或者结构化的数据对象对数据库进行增、删、改、查等操作。

本地数据存储有其天生的弊端,当用户更换设备或卸载应用时,存储在本地的数据就会丢失。为了解决这个问题,在Android 2.2中,引入了云存储的支持,就是不仅将数据存储在本地,同时还将其同步到Google提供的远端服务器中(所谓的云端)。这样,即使存储在本地的数据遗失了,也可以通过网络再同步回来,既保证了数据安全性,又有利于改善用户体验。

在实际开发中,数据存储最重要的是策略合适。面对不同的数据应该用怎样的策略存储比较合适,需要综合性能、简单性、可靠性等多种因素来考虑,关于数据存储的更多介绍和实践,见第9章。1.2.3 网络通信

如今的移动设备早就不再是一个信息孤岛,种类繁多的网络接入方式,使得它可以和其他设备互联互通、传递消息。

在Android中,系统会负责底层网络的连接和管理,开发者可以直接通过HTTP或Socket与远端服务器建立连接,而不需要关心是通过GPRS、EDGE、3G还是WiFi来建立的。Android不仅支持点到端的连接,同样还支持点到点的蓝牙连接、NFC连接等。蓝牙的实现,主[1]要依托于开源项目BlueZ。

Android不断地支持各种新的设备间连接手段,比如,持续地对NFC的改进,对WiFi直连的支持(从4.0开始),对于开发者而言,了解这些新的特性,也就是掌握了未来的方向。

除了网络连接方面的支持,Android还内嵌了基于Webkit实现的浏览器控件,用来完美地展示本地或远端的Web页面。在android.webkit包中包括相关的支持类型,它不仅可以展示简单的HTML页面,对JavaScript和CSS的支持也非常好,并且可以将本地的Java代码内嵌成JavaScript脚本来使用,是所有开发者的福音。

对于长时间需要联网的应用而言,如何节约流量、节约电量、保持连接的稳定性,都是非常重要的技术点,关于网络通信的更多分析和实践,将会在第10章进一步展开。

[1]BlueZ的官方主页:http://www.bluez.org/。1.2.4 地理信息

以手机为代表的移动设备,其最大的特征就是可以随身携带,人到哪里,设备就跟到哪里。这使得通过移动设备获取用户当前位置的地理信息变得顺理成章,相关应用层出不穷。

地理信息的相关应用,一直是Android系统中最热门的应用开发方向之一。这在很大程度上是因为Android对于地理信息获取的支持十分强大,不仅可以基于GPS定位,还可以通过网络利用基站信息进行定位。基站定位的精度要比GPS低一些,通常在数十米到数百米之间,但它的适应能力更强,只要有移动信号和网络连接,便可以进行定位,而不像GPS那样会受到周围建筑的影响。同时,基站定位能耗更低,绿色环保,并且可以帮助没有GPS设备的低端移动设备进行定位,使得Android设备真正做到定位无疆界。

除了支持对地理信息的获取,Android还内嵌了地理信息编码、Google地图等服务,可以帮助更好地展示地理信息。美中不足的是,Google地图只是作为一个可选的类库,尤其是在国内很多“特别定制”的移动设备中,都没有将其内嵌进去。如果你的应用依赖于该类库,将无法在这些设备上安装或运行。因此,如果你只是期望将地图显示作为一个附属功能,可以考虑从外部调用本地或网络的地图应用进行展示,或者是利用浏览器控件内嵌有地图信息的Web页面。

对于相关开发者而言,精准和实时地为用户提供地理信息,无疑是非常关键的,第11章将会详细介绍在Android中如何更精确地进行定位。1.2.5 图形和多媒体处理

对于现今的移动设备而言,声、色、型都是必不可少的组成部分。Android支持MPEG4、H.264、MP3、AAC、AMR、JPG、PNG、GIF[1]等主流的图像和音视频格式。Android的音视频处理主要依托于开源的OpenCORE项目,这是一个基于C/C++实现的音视频处理库,放在Android的核心类库层,可以进行多种格式文件的编解码及流媒体[2]处理。在图像处理方面,主要是通过开源项目Skia来支持,它可以帮助读写图像数据,进行位图到PNG、JPG格式图像的编解码。不过,在Android中处理大尺寸的图像数据需要非常小心谨慎,因为它往往需要将图像数据加载到内存中来,而每个Android进程仅有16MB的堆空间,一不小心内存溢出了,整个应用不可避免就会崩溃。

Android中对2D图形的使用,主要经由android.graphics.drawable包来实现。该包中的类都是android.graphics.drawable.Drawable基类的具体实现,在实际工程中碰到的大部分2D图形、图像及动画的呈现,几乎都可以通过它们来实现。它不仅支持图形、图像、纯色、渐变等静态效果的绘制,还可以分层、分状态地显示各种动画效果;并且,它支持局部或全局的缩放、拉伸和旋转等操作,从而帮助开发者轻松搭建秀色可餐的应用。

在3D处理方面,Android则搭配了OpenGL ES(OpenGL for [3]Embedded System)。开发者可以通过javax.microedition.khronos.opengles包和android.opengl包,来使用OpenGL进行开发。而对于很多游戏开发者而言,为了追求更高的效率,可以抛开Java的封装,直接通过Android NDK提供的OpenGL ES接口来进行开发。本书并不会详细介绍图形处理方面的知识,对于大多数图形处理的开发者而言,图形学知识和OpenGL的使用才是重点,具体的开发平台并不会成为他们的桎梏。

对于所有多媒体数据的操作,内存开销永远是非常重要的话题。如何在降低内存消耗的前提下,更流畅地处理多媒体数据,本书第12章将会详细讲解。

[1]Android支持的格式参见:http://developer.android.com/guide/appendix/media-formats.html。

[2]Skia的官方网站:http://code.google.com/p/skia/。

[3]关于OpenGL ES的介绍,请参见:http://www.khronos.org/opengles/。1.2.6 外部设备

每个移动设备都会有形形色色的输入输出等外部设备,支持这些设备是Android义不容辞的职责。Android可以兼容各类输入设备,包括各种键盘、触摸屏、轨迹球等。同时,Android也可以支持各种摄像头,以完成自动聚焦、拍照、录像、预览等操作。

除了这些基本设备,Android还支持各种类型的感应器,包括加速度传感器、压力传感器、温度传感器、光学传感器,等等。通过android.hardware.SensorManager对象,它可以获得设备上所有的传感器信息,并从中获取相关数据,开发出具有更出色体验的应用。

除此之外,Google还为Android植入了强大的语音识别服务,它将麦克风收集来的语音信息传输到远端服务器进行匹配,转换成对应的文本信息再传输回来。通过这样的架构模式,它可以有效地识别出最新最热门的词语和句子,为用户提供多种输入方式。1.2.7 特色功能模块

除了上述功能,Android还有一些比较有特色的功能设计,合理地使用它们,才能打造最地道的Android应用。

Android有统一的账号管理系统,当用户将账号登录到了Android系统中,Android中的其他应用便可以利用这些账号信息进行认证。统一的账号系统避免了用户注册和登录的麻烦,降低了他们的使用门槛,也为开发者提供了新的机会。

Android还有全局的事件通知(Notification)机制。当应用需要将消息即时推送给用户时,可以利用Android的android.app.NotificationManager对象,将通知消息发送到系统的状态栏中,并利用声音、震动、图标等方式提醒用户。这种统一的事件通知模型,不但降低了用户的学习成本,更使得开发者不再需要绞尽脑汁地去想如何具体实现了。

Android对大一统的框架机制情有独钟,除了事件通知机制,应用内搜索框架也是其一。Android的用户,可以随时通过搜索键,呼出一个搜索框对当前关注的信息进行搜索,而每个应用都可以根据自己的需求,去提供符合当前用户需求的搜索内容。

除此之外,Android还提供了一套桌面小工具(App Widget)模型,开发小工具和开发标准的Android应用大同小异,用户可以选择喜爱的小工具放在桌面上,从而可以更方便地获取信息。

Android有如此多的特色功能,该如何正确地使用它们,才能够真正为应用增色,是本书的第13章将详细介绍的内容。1.3 Android的架构特征和设计思想

平台的设计思想,决定了整个平台的架构和功能设计。对于开发者而言,理解了平台的设计思想,就好比练武之人打通了任督二脉,能够将对功能的认知融会贯通起来,使用时也会更为得心应手。

比如,Symbian的设计很多都是从提升性能的角度来出发的,因此舍弃了很多对界面效果及接口可用性的优化。因为在Symbian的时代,移动设备的硬件处理能力还很弱,设备屏幕小,分辨率很低,移动应用也远没有如今丰富。Symbian不需要提供强大的界面框架,也不需要过多地考虑应用间的关联。

然而,随着移动设备性能的不断提升,用户对移动应用需求的不断增加,Symbian等传统移动平台的设计就显得过时了,不再能满足开发者和用户的需求了。而Android正是基于当前环境进行设计的,它考虑了设备的兼容性,增强了应用之间的功能复用,优化了对网络服务的支持,简化了应用开发的难度。

很多时候,开发者单独看Android的一些设计,就不由自主地想问:“为什么要这样设计?”也许,尝试从Android的设计思想出发去理解,很多疑问就迎刃而解了。1.3.1 平台开放性

Android期望打造的是一个开放的平台,可以运行在各式各样的设备环境下。开放性对平台架构设计最大的要求,就是兼容性,即兼容不同硬件的设备、屏幕尺寸、外设、语言环境,等等。

在底层,Android架设在Linux之上。Linux强大的可移植能力,保证了Android可以在不同的硬件环境中运行。而在上层,Android为应用提供了很多能够增强兼容性的机制,比如:基于资源目录的应用资源体系。开发者可以针对不同的设备环境,分别定制描述同一界面对象的资源文件,然后分别放入特定的资源目录中,Android系统会在运行时寻找最符合当前设备环境的资源文件,从而提供最合适的用户体验。

对于开发者而言,应该在应用开发的过程中充分考虑兼容性的因素,并利用Android提供的设计和方法,提升应用的兼容性,保证在不同的Android设备和版本上的应用都有最好的用户体验。1.3.2 基于组件的应用设计

Android之父Andy Rubin曾在采访中说过,他在设计Android的时候,就期望Android能够像Facebook那样,从不同的应用中挑选所需的模块,像搭积木一样构造新的应用。

Android的应用是高度组件化的,开发者需要依照Android规范,编写一个个独立的组件,然后通过配置文件对每个组件的需求和能力进行描述,Android系统会统一调度这些组件。这就意味着,应用中的某一项功能,可能是由来自很多应用的若干组件共同完成的,各个Android应用,只有明确的组件边界,而不再有明确的进程边界和应用边界。

正是由于这种组件化的设计思想,衍生出了很多相关的设计,比如基于意图(Intent)的通信模式、进程托管、组件的生命周期,等等。将这些设计单独独立出来看会让人感觉有些莫名其妙,但站在组件化的角度来思考,却都是如此合情合理。

对于开发者而言,需要充分理解基于组件化的应用设计模式,根据Android的机制,合理地管理应用中的数据,控制好对象的生命周期,并充分利用组件化带来的灵活性和可复用性。

本书的第3章至第6章将针对基于组件的应用设计,进行更详尽的实践和分析。1.3.3 基于网络服务的平台

iPhone的出现,把网络服务真正带入了手机应用中。网络从此不再是手机等移动设备的附庸,而是彻底地与它们融为一体。而在Google的引导下,Android在融合网络服务方面更进一步,将网络服务融合进了Android的灵魂。

Android不仅无缝地支持GPRS、EDGE、WiFi等各类移动网络,还内嵌了强大的浏览器控件。同时,Google为Android提供了Google地图、Google搜索、基于基站定位、云存储等一系列网络服务,并提供了统一的账号系统,解决了网络服务身份认证的问题,将设备和云端服务无缝地连接了起来。并且,通过Android Market、AdMobile等服务,Android营造了完整的应用生态圈。可以预见,在Google的主导下,Android必将越来越网络服务化。

对于Android开发者而言,网络服务化意味着新的产品和商业机会,基于云端服务的应用将会迎来新的生机。1.4 小结

本章介绍了Android的架构思想和主要模块,期望能帮助读者从整体上鸟瞰Android的全貌,为后续更深入地了解Android的功能和实现打好基础。

而理解Android系统的设计思想,对于开发者设计产品也是大有帮助的,顺应Android的设计思想去构造应用,比之逆行而上做Android不擅长的事情,会有更好的前景。第2章Android源代码的下载和编译2.1 Android源代码的获取和编译2.2 Android源代码结构2.3 Android源代码的阅读和编辑2.4 小结开源无疑在软件行业是最美妙的力量之一,当某个领域出现了一款优秀的开源项目时,该领域的准入门槛就被大大降低,各种民间智慧就可以“破门而入”,进而推动整个领域的蓬勃发展。所以说,Android开发者是幸福的,因为自己所耕耘的平台是开源的。对于开发者而言,Android的源代码是最好的学习资料,虽然它没有文档和书籍那样易于阅读,也不如上论坛讨教、咨询前辈那般高效便捷,但它提供的内容是最丰富、直接和深刻的。通过阅读源代码,开发者可以更好地了解Android的架构设计模式和系统的核心机理,而当遭遇到难以理解的底层实现甚至Bug时,通过查看源代码,可能只需要一两分钟的时间,便可以抓住根源,找到合适的方式绕开这个Bug。甚至,还可以自力更生地解决Bug,并提交给Android项目,让所有在该平台辛勤工作的开发者们获益其中,这是一种别样的幸福和荣耀。同时,源代码也是增强版的Android SDK。SDK中常有一些用法很晦涩的接口,通过了解Android的接口实现,开发者可以从中学习到最地道的接口使用方式。我曾在实际开发中被Android的联系人操作绕得晕头转向。Android联系人的数据存储结构很复杂,并且随着Android版本变迁,接口不断变更,兼容性越来越差。多亏有了Android源代码,通过参看系统自带的联系人应用实现,我总算在一片黑暗中摸到了通向光明的道路,走出了这片深渊。总之,作为一个Android开发者,不论你从事的是哪一方面的开发工作,存留一份源代码,总有一天会需要它。本章将介绍与Android源代码的获取、编译、阅读等方面相关的问题,具体包括:❑Android源代码的下载和编译❑Android源代码的结构❑Android源代码的阅读环境构建❑Android源代码的Bug反馈和修改提交2.1 Android源代码的获取和编译

如果通过前面介绍,你开始对Android源代码有了一些兴趣或好奇,那么不要犹豫,动手把它获取过来。从Android开源项目的官方

[1]网站,可以了解到如何获取源代码以及如何编译源代码、向各种设备做移植等方面的内容。2.1.1 环境搭建

Android源代码的下载、编译等工作通常在Ubuntu等Linux操作系统或者Mac OS上进行。如果在Windows上来进行,可以使用虚拟机,这会需要足够强大的机器配置,步骤也相对更为复杂。本章后续对源代码相关操作的说明(除了特别说明的地方),都默认在32位的Ubuntu上(8.10以上)来进行,在环境准备等方面和其他操作系统相比,可能会有一些差异,详情可参见官方网站上的说明。

在获取和编译源代码之前,你需要为它打造一个安全舒适的环境。在32位Ubuntu上,你可以用如下指令去获得相关的源码管理和[2]编译工具:

$sudo apt-get install git-core gnupg sun-java5-jdk flex bison gperf libsdl-dev libesd0-dev libwxgtk2. 6-dev build-essential zip curl libncurses5-dev zlib1g-dev

如果上述指令执行失败,可能是因为sun-java5-jdk过于老旧,其apt源不再作为操作系统的默认配置,你需要先替换一下apt的源列表。具体操作方式是:打开/etc/apt/source.list文件,将其中的版本代号信[3]息(比如karmic)换成jaunty,保存,并执行如下指令用以更新apt设置:

$sudo apt-get update

完成之后,再次执行上一条apt-get指令,整个源代码管理和编译的环境就搭建完成了。

特别需要提醒的是,如果想编译2.3以上版本的Android源代码,需要jdk6,而稍老一些的Android源代码,需要使用jdk5进行编译,而不能使用更高版本的jdk进行编译。

[1]Android开源项目的网址在:http://source.android.com。

[2]编译Android的环境在不断的变化中,比如,在Android 2.3之后,其源码就需要使用Java 6的SDK进行编译了。如果需要搭建Android编译环境,最好是参照最新的官方介绍:http://source.android.com/source/initializing.html。

[3]请参考:http://code.google.com/p/androidbmi/wiki/Compile。2.1.2 源代码获取[1]

Android的源代码是用Git来进行管理的。Git是一款高效的源码管理工具,关于它的特点和具体指令,可以参见其官网。为了更好地进行源代码管理操作,Android基于Git封装了一个工具,叫做Repo。它隐藏了较为繁琐的Git指令细节,帮助开发者更方便地进行源码的同步。

按照以下步骤,可以下载并配置好Repo:

$cd~

$mkdir bin

$curl http://android.git.kernel.org/repo>~/bin/repo

$chmod a+x~/bin/repo

有了Repo,就可以开始下载源代码了。首先,需要建立一个Android工作目录(本书的后续内容,均以粗体的MY_ANDROID代表该工作目录):

$mkdir MY_ANDROID

$cd MY_ANDROID

如果是想同步版本库中最新的源代码,可以按照如下指令,在Android工作目录MY_ANDROID中初始化版本库:

$repo init-u git://android.git.kernel.org/platform/manifest.git

类似地,如果期望同步特定分支上的源代码,可以通过-b参数来指定分支的版本或别名,比如,同步cupcake(即Android 1.6)分支上的最新代码,可如下执行:

$repo init-u git://android.git.kernel.org/platform/manifest.git-b cupcake

在初始化版本库的工作完成以后,就可以使用同步指令,将源代码同步更新到本地:

$repo sync

如果是首次在工作目录下调用该指令,它会将源码库中指定版本的文件完整地下载到本地,而日后再执行该指令,则会和本地已有文件做比较,将更新的部分同步并进行合并。

Android的源代码大小约为2GB,为了给后续工作留出充足够的余量,建议最好准备6~10GB空间,以及1.5GB的内存空间。在硬盘容量动辄上百GB的今天,这个需求并不算太过分。

通过上述方法获取到的源代码,包含了Android应用层、框架层、运行时和底层类库的所有代码,可以用来编译出运行在模拟器上的Android ROM,以及相关的开发工具。但是,这份源代码并不能编译出可以在真实设备上运行的ROM,因为还缺少了Linux操作系统层和硬件抽象层相关的代码。如果你希望为自己或他人的手机打造一份印有自己Logo的Android ROM,那么需要将这些缺失的内容(可能是[2]源码,也可能是已编译好的类库和资源)同步至本地。

包含在Android源代码库中的其他所需代码,可以通过修改工作目录MY_ANDROID下的.repo/local_manifest.xml来让源码管理工具帮你同步。比如,添加Linux的核心代码以及厂商提供的一些开源的设[3]备相关模块,可以将local_manifest.xml修改如下:

<?xml version="1.0"encoding="UTF-8"?>

<manifest>

<project path="kernel"name="kernel/msm"revision="refs/heads/

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

下载完整电子书


相关推荐

最新文章


© 2020 txtepub下载