1.安卓是什么?
安卓是为移动设备准备的软件栈,它包含一个Linux操作系统和一些中间件。通常,它还带有一系列关键应用,比如通讯录,地图应用,浏览器等等。
安卓由谷歌开发和维护,它是一个开源项目,感兴趣的话,可以下载它的源代码。
近年来,安卓已被各大移动设备制造商所采用,作为专利移动设备平台的替代。比如,摩托罗拉、索爱、三星、HTC等制造商都是用安卓平台。
上图是安卓的架构图,来源于安卓开发者网站,安卓结构大致可以分为4层。
第一层是应用层,一般的安卓设备都会预装一些应用。比如通讯录,打电话,网络浏览器,诸如此类的应用。安卓的有趣之处在于它是一个开放式平台,像我们这样的第三方开发者可以定制自己的应用并提供给使用安卓设备的用户,这就是在安卓应用框架上建立应用。
第二层是应用框架,和第一层都是蓝色的,这些层都是用Java。移动设备上自带的所有应用以及第三方或者自己开放的应用都是用Java语言写的,是一系列相互紧密联系的应用框架。其中有一系列不同的子框架,有管理活动的框架,有窗口管理框架,有管理设备本地内容的框架,有处理电话事件的框架,有位置管理框架等等。框架本身则是在一系列库之上写出来的,也就是绿色这一层。
第三层是库。这些库以及安卓运行时,库都是用C和C++写的,这些库是自带的,有一些由谷歌实现,另一些是集成的开源项目。比如SQLite是一个轻量级数据库平台,它是安卓设备包含的开源项目和iPhone使用的软件包是一样的,本地数据库是SQLite,还有浏览器的WebKit库等等。而安卓运行时则是基于Dalvik虚拟机,谷歌漂亮地实现了它,这是一种Java运行环境。
第四层是Linux内核层,所有上面的这些都建于Linux内核之上。安卓运行的是Linux 2.6内核,这是硬件之上最直接联系的软件层,它管理最根本的所有资源。需要强调的是,自带应用程序和你作为开发者所开发的应用都是基于相同的应用框架,也就是说,安卓的API没有特殊和秘密可言。
再看Dalvik虚拟机,这是谷歌实现的虚拟机。众所周知,安卓是面向手机和平板电脑的,这些设备资源都相对有限,没有很强的处理能力,没有很多内存,而且还受电池电源限制,于是谷歌开发了单独的虚拟机,这是专门在较慢CPU上运行,内存占用最小化,在无交换空间的OS上运行及节能所设计的。另外,安卓2.2 或者称为Froyo,支持JIT编译,也就是即时编译,运算密集型工作,将得到3到5倍的性能提升。Dalvik虚拟机是基于寄存器的,而不是堆栈机器,它能最小化指令分配和内存访问。总体而言,它将提供更高效的指令流,也就是说,每条指令上,相比Sun Java虚拟机这种堆栈机器能得到的语义内容会多得多。
构件块:它们是安卓应用程序的基本组件。在写安卓代码之前,了解最基础的安卓概念是很有必要的。
首先是活动的概念。在安卓中,活动代表用户做某事,这通常呈现在同一屏幕上,但屏幕上可以有多个视图 ,下面再定义一下安卓中的视图 ,视图View是安卓GUI基类 ,用来在屏幕上绘制矩形以及对屏幕区域发生的事件作出响应,它是图形化及交互的基本抽象。建立新活动则通过扩展安卓Activity类实现,有个类叫Activity。应用程序中要创建新活动时,就需要从Activity基类中派生。下面举个活动的例子,列出电话上所有的联系人,让用户选一个,这就是活动的例子。
下一个概念是服务。可以将服务考虑为没有用户界面的应用或应用组件,它在后台运行,为用户实现某些功能,但没有用户界面,不在前台显示。创建服务时,需要扩展安卓的Service类。比如媒体播放器是很好的服务例子,用户选择播放曲目时,它有界面,但切换到其它应用时,播放器就不在前台,此时,应该把它放到后台运行,让播放器保持播放就要用到服务,此时前台运行的是其它应用。
下一个构件是所谓的“广播接收器”。广播接收器接收并对广播作出反应,它也没有用户界面,但能调用用户界面的活动。还是一样,要创建广播接收器,需要扩展安卓的BroadcastReceiver基类。假设我写了一个Flickr应用,我要整合Flickr网站功能,使得只要用户用设备拍照,应用程序就能收到通知,然后自动将照片上传到Flickr账户,这就要用到广播接收器,我可以注册到拍照事件,当它发生时,安装平台会广播给我的广播接收器,这样,我可以处理事件了。
最后一个构件块是内容提供器。内容提供器是用来管理应用程序数据的,内容提供器可以让一个应用的数据用于设备上的其它应用,也可以用于应用自身,只要应用中含有内容提供器,我们就能使用内容提供器访问其数据。数据一般存于设备的,SQLite数据库中。不过安卓还支持文件系统的概念,它拥有一些键值对组成的首选项,也就是说,本地数据存储有几种不同方式。建立内容提供器,需要扩展安卓ContentProvider类。比如,一般安卓设备都有联系人应用,存在联系人数据库,里面是联系人的电话,邮箱等等,所以安卓中默认存在一个内容提供器,让其它应用能够访问此联系人数据库。
以上就是安卓应用中的四大关键构件块,下面大概介绍下应用程序。
从UI的角度看,安卓一项很棒的特性是应用框架让其很容易在一个应用中无缝服用另一个应用中定义的功能。任一个安卓应用,都以单独的Linux进程运行,而且每个应用安装后,都具有唯一的用户ID。从用户界面角度而言,安卓会管理所谓的“活动栈”,这些活动将形成堆栈,安卓会管理所有的细节问题。安卓活动大体上就是交互式安卓应用的组件,每个应用中存在一个或多个活动,活动由活动栈管理,于是应用能够调用其它应用中定义的活动。
安卓活动的生命周期。
活动总共有三种状态,一种是停止,一种是暂停,此时在前台仍然部分可见,但另一个应用运行在它之前,第三种是活动,即前台完全可见,活动周期图说明了活动如何在不同状态之间转换。Activity基类中,存在hook函数,在状态转换时,由底层框架调用。活动开始时,代码中使用框架中的onCreate hook函数,可见后,还有onStart、onResume 此时在运行。如果其它活动要到此活动前面运行,原来的活动至少会被部分挡住,虽然仍是可见状态,但会暂停,此时原活动通过onPause方法暂停。当原活动完全不可见时,另一个活动使其被完全切断,就会调用onStop。如果用户退出应用,或者应用由于其它原因终止,就会调用onDestroy。框架还可能这样来管理,哪怕应用不在前台,但占用很多资源,安卓也会终止此应用。移动设备的资源是有限的,如果内存保持很低,安卓就会选择性停止当前不在前台,但占用内存的应用,会静悄悄地终止这些应用。当然,如果用户最终又回到该应用,也许是通过活动栈,然后回到该应用,这就需要onCreate,活动再次创建和实例化,停止时,需要写代码存储应用状态以备恢复时使用,毕竟不知道终止何时发生,不确定性太大,依赖于资源消耗,所以说,掌握好活动的生命周期是必要的,掌握好这些hook方法是有必要的。
一个问题是如何从一个活动转到另一个活动,当应用中包含一个或多个活动时,什么能让我们从一个转到另一个,在安卓中,我们称之为intents(意图)。意图是从一个活动传给另一个的异步信息,一般,意图包含两段数据,首先是动作,然后是该动作所需数据的实际URL。安卓中,还分隐性意图和显性意图。显性意图是指活动中明确了另一个活动是什么,这是显性的,可以在意图中硬编码,想转到的是什么活动。不过更一般的方式是隐性意图,隐性意图中,只说明要做什么,只说明要完成的一般性动作,以及完成该动作可能需要的数据,活动所发出的意图可以像这样,它将发送意图,安卓平台看到意图之后会想,设备上什么活动能够处理该意图,以后写代码的时候就会知道,写活动时会写所谓的意图过滤器,我们会明确指出,哪个活动能响应哪些意图,安卓会找出设备上有哪些活动,能够运行特定意图,然后它会将控制转给此活动。下面问个明显的问题,如果比较模糊呢?如果有N个活动能响应特定意图呢?此时,安卓会弹出对话框给用户,将可供选择的应用图标列出来,供用户选择。比如,设备上网络浏览器可能不止一个,有一个标准的WebKit浏览器,可能还要第三方浏览器,如Opera,此时如果某应用想要弹出浏览器,然后试图显示某URL的网页,安卓就会弹出选框让用户选择,用户还能选一个设置为默认值。各应用既能有机结合,又没捆绑在一起,这非常棒。如果不喜欢原来的默认设置,你可以用自己的应用换掉它,用新设的默认行为来响应意图。