Android应用程序用Java做为开发语言。aapt工具把编译后的Java代码连同其它应用程序需要的数据和资源文件一起打包到一个Android文件包中,这个文件使用.apk做为扩展名,它是发布应用程序并安装到移动设备的媒介,用户只需下载并安装此文件到他们的设备即可。单个.apk文件中的所有代码被看作是一个应用程序。
从很多方面来看,每个Android应用程序都存在于它自己的世界之中:
- 默认情况下,每个应用程序均运行于它自己的Linux进程中。当任一应用程序开始执行时,Android启动一个进程,而当应用程序不再需要此进程而其它应用程序又需要系统资源时,则关闭这个进程。
- 每个进程都运行于自己的Java虚拟机(VM)中。所以应用程序代码实际上与其它应用程序的代码是隔离的。
- 默认情况下,每个应用程序均被赋予一个唯一的Linux用户ID,并加以权限设置,使得那个应用程序的文件仅对这个用户、这个应用程序可见。当然,也有其它的方法使得这些文件同样能被别的应用程序所访问。
可以让两个应用程序共有同一个用户ID,这种情况下他们可以看到彼此的文件。为了保护系统资源,拥有同一个ID的应用程序将运行在同一个Linux进程,以及同一个虚拟机之中。
1.1 Application组件
Android的核心功能之一就是一个应用程序可以使用其它应用程序的元素(如果那个应用程序允许的话)。比如说,如果你的应用程序需要一个图片滚动列表,而另一个应用程序已经开发了一个合适、而且又允许别人使用的相同列表,可以直接调用那个滚动列表来实现功能,而不用自己再开发一个。而应用程序并没有包含或链接其它应用程序的代码,它只是在需要时启用了其它应用程序的那部分功能而已。
为达到这个目的,系统必须在一个应用程序的一部分需要时启动这个应用程序,并将那部分的Java对象实例化。与其它系统上的应用程序不同,Android应用程序没有为应用程序提供单独的程序入口(比如说,没有main()方法), 相反,而是提供了一些核心组件,系统可以在需要时实例化,运行这些组件。共有四种组件类型:
Activity(活动)
Activity是为响应用户操作而展示的可视化用户界面。比如说,一个Activity可以展示一个菜单项列表供用户选择,或者显示一些包含说明的照片。一个短消息应用程序可以包括一个用于显示做为发送对象的联系人列表的Activity,一个给选定的联系人写短信的Activity以及翻阅以前的短信和改变设置的Activity。尽管它们一起写作完成了一个完整的用户界面,但每个Activity都与其它的Activity保持独立。都是通过以Activity类为基类的子类实现。
一个应用程序可以只有一个Activity,或者,如刚才提到的短信应用程序那样包含多个。每个Activity的作用,以及其数目,自然取决于应用程序及其设计。通常,其中一个Activity被标记启动Activity,用户在应用程序启动的时候首先看到该Activity的内容。用当前Activity启动一个新的Activity即可转向其他的Activity。
每个Activity都被给予一个默认的窗口以进行绘制。通常,这个窗口是满屏的,但它也可以是一个小的位于其它窗口之上的浮动窗口。Activity也可以使用额外的窗口——比如,在Activity运行过程中弹出一个需用户反应的小对话框,或是当用户选择了屏幕上特定项目后弹出的重要信息窗口。
窗口显示的可视内容是由一系列视图构成的,这些视图均继承自View基类。每个视图均控制着窗口中一块特定的矩形空间。父级视图包含并组织它的子视图的布局。叶节点视图(位于视图层次最底端)在它们控制的矩形中进行绘制,并对用户对其实施的操作做出响应。所以,视图是Activity与用户进行交互的界面。比如说,视图可以显示一个小图片,并在用户指点它的时候产生行为。Android有很多既定的视图供用户直接使用,包括按钮、文本域、滚动条、菜单项、复选框等等。
视图及其层次是由Activity.setContentView()方法放入Activity的窗口之中。内容视图(Content View)是位于视图层次根位置的视图对象。(参考用户界面章节的内容获取关于视图及其层次的更多信息。)
Service(服务)
服务没有可视化的用户界面,而是在一段时间内在后台运行。比如说,一个服务可以在用户做其它事情的时候在后台播放背景音乐、从网络获取一些数据或者计算一些东西并提供给需要这个运算结果的Activity使用。每个服务都继承自Service基类。
媒体播放器播放播放列表中的曲目是一个不错的例子。播放器应用程序可能有一个或多个Activity来给用户选择歌曲并进行播放。然而,音乐播放这个任务本身不应该为任何Activity所处理,因为用户期望在他们离开播放器应用程序而开始做别的事情时,音乐仍在继续播放。为达到这个目的,媒体播放器Activity应该启用一个运行于后台的服务。而系统将在这个Activity不再显示在屏幕之后,仍维持音乐播放服务的运行。我们可以连接(绑定)至一个正在运行的服务(如果服务没有运行,则启动)。连接之后,可以通过那个服务暴露出来的接口与服务进行通讯。对于音乐服务来说,这个接口可以允许用户暂停、回退、停止以及重新开始播放。
如同Activity和其它组件一样,服务运行于应用程序进程的主线程内。所以它不会对其它组件或用户界面有任何干扰,它们一般会派生一个新线程来进行一些耗时任务(比如音乐回放)。参见下述进程和线程。
Broadcast(广播接收器)
广播接收器是一个专注于接收广播通知信息,并做出对应处理的组件。很多广播是源自于系统代码——比如,通知时区改变、电池电量低、拍摄了一张照片或者用户改变了语言选项。应用程序也可以进行广播——比如说,通知其它应用程序一些数据下载完成并处于可用状态。
应用程序可以拥有任意数量的广播接收器以对其所有感兴趣的通知信息予以响应。所有的接收器均继承自BroadcastReceiver基类。
广播接收器本身不显示用户界面。但它可以启动一个Activity来响应收到的信息,或者用NotificationManager来通知用户。通知可以用很多种方式来吸引用户的注意力──闪动背灯、震动、播放声音等等。一般来说是在状态栏上放一个持久(Persistent)的图标,用户可以打开它并获取消息。
ContentProvider(内容提供者)
内容提供者将一些特定的应用程序数据提供给其它应用程序使用。数据可以存储于文件系统、SQLite数据库或其它方式。内容提供者继承于ContentProvider 基类,为其它应用程序读取和存储它管理的数据实现了一套标准方法。然而,应用程序并不直接调用这些方法,而是使用一个 ContentResolver 对象,调用它的方法。ContentResolver可以与任意的内容提供者进行会话,与Provider合作来管理其涉及的所有相关交互通讯。
参阅单独的内容提供者章节获得更多关于使用内容提供者的内容。
每当出现一个需要被特定组件处理的请求时,Android会确保那个组件的应用程序进程处于运行状态,或在必要的时候启动它。并确保那个相应组件的实例存在,必要时会创建那个实例。