文/范怀宇
了解Android功能模块的概况,就像看Android的“个人简历”一样,帮助我们对它的能力有整体上的认识,进而在应用开发之前可以更好地评估技术上的可能性和风险性。
界面框架
每个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的界面框架进行详细的介绍,其中,会结合一些优秀的界面实现来实际探索如何构建足够高效的交互界面。
数据存储
对于很多应用而言,大到复杂的结构化数据,小到简单的设置信息,都有数据存储的需求。广义上看,应用数据存储有两种方式:一种是将数据存放在本地存储设备中;而另一种则是通过网络,将数据存储在远端服务器中,也就是常说的“云存储”。
Android本地数据存储的最大特点是数据的私有化。每个应用的配置信息和数据库文件等数据,都是其私有的,其他应用没有权限进行读写,从而保证了应用数据的安全性。而对于如何将其数据共享给其他应用,一个策略是构造一个数据源组件(Content Provider),其他应用的组件可以通过数据源组件的接口访问它所提供的数据;而另一个常用的策略是将数据放入扩展存储设备(通常是SD卡等扩展存储卡)中,在该存储设备中的数据,可以被所有应用共同访问。比如,Android的多媒体数据文件通常存储在扩展存储设备中,以便各个图像应用、音乐播放应用等读写。
Android对本地数据的存储,可以有多种文件格式,比如普通数据文件、设置文件和数据库,等等。设置文件(Preferences)是专门针对存储应用设置信息而设计的,它依照键值对的形式进行保存,Android从界面到存储都做了完整的支持。而Android的数据库依靠Sqlite的支持,在android.database包中提供了更为便捷的读写类库支持,开发者可以使用SQL语言或者结构化的数据对象对数据库进行增、删、改、查等操作。
本地数据存储有其天生的弊端,当用户更换设备或卸载应用时,存储在本地的数据就会丢失。为了解决这个问题,在Android 2.2中,引入了云存储的支持,就是不仅将数据存储在本地,同时还将其同步到Google提供的远端服务器中(所谓的云端)。这样,即使存储在本地的数据遗失了,也可以通过网络再同步回来,既保证了数据安全性,又有利于改善用户体验。
在实际开发中,数据存储最重要的是策略合适。面对不同的数据应该用怎样的策略存储比较合适,需要综合性能、简单性、可靠性等多种因素来考虑。
网络通信
如今的移动设备早就不再是一个信息孤岛,种类繁多的网络接入方式,使得它可以和其他设备互联互通、传递消息。
在Android中,系统会负责底层网络的连接和管理,开发者可以直接通过HTTP或Socket与远端服务器建立连接,而不需要关心是通过GPRS、EDGE、3G还是WiFi来建立的。Android不仅支持点到端的连接,同样还支持点到点的蓝牙连接、NFC连接等。蓝牙的实现,主要依托于开源项目BlueZ。
Android不断地支持各种新的设备间连接手段,比如,持续地对NFC的改进,对WiFi直连的支持(从4.0开始),对于开发者而言,了解这些新的特性,也就是掌握了未来的方向。
除了网络连接方面的支持,Android还内嵌了基于Webkit实现的浏览器控件,用来完美地展示本地或远端的Web页面。在android.webkit包中包括相关的支持类型,它不仅可以展示简单的HTML页面,对JavaScript和CSS的支持也非常好,并且可以将本地的Java代码内嵌成JavaScript脚本来使用,是所有开发者的福音。
对于长时间需要联网的应用而言,如何节约流量、节约电量、保持连接的稳定性,都是非常重要的技术点,关于网络通信的更多分析和实践,将会在第10章进一步展开。
4.地理信息
以手机为代表的移动设备,其最大的特征就是可以随身携带,人到哪里,设备就跟到哪里。这使得通过移动设备获取用户当前位置的地理信息变得顺理成章,相关应用层出不穷。
地理信息的相关应用,一直是Android系统中最热门的应用开发方向之一。这在很大程度上是因为Android对于地理信息获取的支持十分强大,不仅可以基于GPS定位,还可以通过网络利用基站信息进行定位。基站定位的精度要比GPS低一些,通常在数十米到数百米之间,但它的适应能力更强,只要有移动信号和网络连接,便可以进行定位,而不像GPS那样会受到周围建筑的影响。同时,基站定位能耗更低,绿色环保,并且可以帮助没有GPS设备的低端移动设备进行定位,使得Android设备真正做到定位无疆界。
除了支持对地理信息的获取,Android还内嵌了地理信息编码、Google地图等服务,可以帮助更好地展示地理信息。美中不足的是,Google地图只是作为一个可选的类库,尤其是在国内很多“特别定制”的移动设备中,都没有将其内嵌进去。如果你的应用依赖于该类库,将无法在这些设备上安装或运行。因此,如果你只是期望将地图显示作为一个附属功能,可以考虑从外部调用本地或网络的地图应用进行展示,或者是利用浏览器控件内嵌有地图信息的Web页面。
对于相关开发者而言,精准和实时地为用户提供地理信息,无疑是非常关键的,第11章将会详细介绍在Android中如何更精确地进行定位。
5.图形和多媒体处理
对于现今的移动设备而言,声、色、型都是必不可少的组成部分。Android支持MPEG4、H.264、MP3、AAC、AMR、JPG、PNG、GIF等主流的图像和音视频格式。Android的音视频处理主要依托于开源的OpenCORE项目,这是一个基于C/C++实现的音视频处理库,放在Android的核心类库层,可以进行多种格式文件的编解码及流媒体处理。在图像处理方面,主要是通过开源项目Skia来支持,它可以帮助读写图像数据,进行位图到PNG、JPG格式图像的编解码。不过,在Android中处理大尺寸的图像数据需要非常小心谨慎,因为它往往需要将图像数据加载到内存中来,而每个Android进程仅有16MB的堆空间,一不小心内存溢出了,整个应用不可避免就会崩溃。
Android中对2D图形的使用,主要经由android.graphics.drawable包来实现。该包中的类都是android.graphics.drawable.Drawable基类的具体实现,在实际工程中碰到的大部分2D图形、图像及动画的呈现,几乎都可以通过它们来实现。它不仅支持图形、图像、纯色、渐变等静态效果的绘制,还可以分层、分状态地显示各种动画效果;并且,它支持局部或全局的缩放、拉伸和旋转等操作,从而帮助开发者轻松搭建秀色可餐的应用。
在3D处理方面,Android则搭配了OpenGL ES(OpenGL for Embedded System)。开发者可以通过javax.microedition.khronos.opengles包和android.opengl包,来使用OpenGL进行开发。而对于很多游戏开发者而言,为了追求更高的效率,可以抛开Java的封装,直接通过Android NDK提供的OpenGL ES接口来进行开发。本书并不会详细介绍图形处理方面的知识,对于大多数图形处理的开发者而言,图形学知识和OpenGL的使用才是重点,具体的开发平台并不会成为他们的桎梏。
对于所有多媒体数据的操作,内存开销永远是非常重要的话题。如何在降低内存消耗的前提下,更流畅地处理多媒体数据,本书第12章将会详细讲解。
6.外部设备
每个移动设备都会有形形色色的输入输出等外部设备,支持这些设备是Android义不容辞的职责。Android可以兼容各类输入设备,包括各种键盘、触摸屏、轨迹球等。同时,Android也可以支持各种摄像头,以完成自动聚焦、拍照、录像、预览等操作。
除了这些基本设备,Android还支持各种类型的感应器,包括加速度传感器、压力传感器、温度传感器、光学传感器,等等。通过android.hardware.SensorManager对象,它可以获得设备上所有的传感器信息,并从中获取相关数据,开发出具有更出色体验的应用。
除此之外,Google还为Android植入了强大的语音识别服务,它将麦克风收集来的语音信息传输到远端服务器进行匹配,转换成对应的文本信息再传输回来。通过这样的架构模式,它可以有效地识别出最新最热门的词语和句子,为用户提供多种输入方式。
7.特色功能模块
除了上述功能,Android还有一些比较有特色的功能设计,合理地使用它们,才能打造最地道的Android应用。
Android有统一的账号管理系统,当用户将账号登录到了Android系统中,Android中的其他应用便可以利用这些账号信息进行认证。统一的账号系统避免了用户注册和登录的麻烦,降低了他们的使用门槛,也为开发者提供了新的机会。
Android还有全局的事件通知(Notification)机制。当应用需要将消息即时推送给用户时,可以利用Android的android.app.NotificationManager对象,将通知消息发送到系统的状态栏中,并利用声音、震动、图标等方式提醒用户。这种统一的事件通知模型,不但降低了用户的学习成本,更使得开发者不再需要绞尽脑汁地去想如何具体实现了。
Android对大一统的框架机制情有独钟,除了事件通知机制,应用内搜索框架也是其一。Android的用户,可以随时通过搜索键,呼出一个搜索框对当前关注的信息进行搜索,而每个应用都可以根据自己的需求,去提供符合当前用户需求的搜索内容。
除此之外,Android还提供了一套桌面小工具(App Widget)模型,开发小工具和开发标准的Android应用大同小异,用户可以选择喜爱的小工具放在桌面上,从而可以更方便地获取信息。
范怀宇,资深Android开发工程师,毕业于清华大学,从事移动开发多年,对Android系统有颇为深入的研究,开发经验十分丰富。曾就职于网易有道,负责完成了有道词典Android版、网易掌上邮Android版、网易八方Android版等项目的开发工作,现就职于豌豆实验室,负责豌豆荚2.0版本的设计和开发。
本文节选自《Android开发精要》艺术,范怀宇著,机械工业出版社出版