Android API Guides——简介(二)
应用基础内容
Android应用采用Java编程语言编写。Android SDK(Software Develop Kit)工具将您的代码-连同任何数据和资源文件-编译到一个APK(Android Package):Android软件包,即带有.apk后缀名的存档文件中。一个APK文件包含Android应用的额所有内容,它是基于Android系统的设备用来安装应用的文件。
安装到设备后,每个Android应用都运行在自己的在自己的Dalvik。(为什么要这样设计呢?为什么不在一个Dalvik呢?如果都在一个Dalvik的话,加入其中一个程序崩溃,所有的程序都将崩溃,故这样设计不是最佳的。每个进程空间确实都有一个Dalvik,但物理内存中实际只有一份,不影响系统效率,而且依靠linux系统的进程相互隔离,挂了一个没其他的都活着。)
- Android操作系统是一种多用户Linux系统,其中的每个应用都是一个不同的用户;
- 默认情况下,系统会为每个应用分配一个唯一的Linux用户ID(该ID仅由系统使用,应用并不知晓)、系统为每个应用中的所有文件设置权限,使得只有分配给该应用的用户ID才能访问这些文件;
- 每个进程都具有自己的虚拟机(VM:virtual machine),因此应用代码是在与其他应用隔离的环境中运行;
- 默认情况下,每个应用都在其自己的Linux进程运行。Android会在需要应用组件时启动该进程,然后在不需要该进程或系统必须为其他应用回复内存关闭进程。
Android系统可以通过这种方式实现“最小权限原则”。也就是说,每个应用都只能访问执行器工作所需的组件,而不能访问其他组件。这样便营造出一个非常安全的环境,在这个环境中,应用无法访问系统中其未获得权限的部分。
不过,应用任然可以通过一些途径与其他应用共享数据以及访问系统服务:
- 可以安排两个应用共享同一Linux用户ID,在这种情况下,他们能够相互访问彼此的文件。为了节省系统组员,可以安排具有相同用户ID的应用在同一Linux进程中运行,并共享同一VM(应用还必须使用相同的证书签署)。
- 应用可以请求访问设备数据(如用户的联系人、短信、可装载存储装置[SD卡]、相机、蓝牙等)的权限。用户必须明确授予这些权限。
应用组件
应用组件是Android应用的基本构建基块。每个组件都是一个不同的点,系统可以通过它进入您的应用。并非所有组件都是用户的实际入口点,有些组件互相依赖,但每个组件都以独立 实体形式存在-每个组件都是唯一的构建基块,有助于定义应用的总体行为。
共有四种不同的应用组件类型。
Activity
Activity表示具有用户界面的单一屏幕。每一个Activity都独立于其他Activity而存在。
Service
服务是一种在后台运行的组件,用于执行长时间运行的操作或为远程执行作业,服务不提供用户界面。例如每当用户位域其他应用中时,服务可能在后台播放音乐或者通过网络获取数据,但不会阻断用户与Activity的交互,诸如Activity等其他组件可以启动服务,让其运行或与其绑定以便其进行交互。
Content Provider
ContentProvider管理一组共享的应用数据。您可以将数据存储在文件系统、SQLite数据库、网络上或您的应用可以访问的任何其他永久性存储位置。其他应用可以通过ContentProvider查询数据,甚至修改数据(如果ContentProvider允许)。例如,Android系统可提供管理联系人信息的ContentProvider,因此任何具有适当权限的应用都可以查询内容提供程序的某一部分(如CpntactsContract.Data),以读取和写入有关特定人员的信息。内容提供程序也适用于读取和写入您的应用不共享的私有数据。例如,记事本示例应用使用ContentProvider来保存笔记。
Broadcast Receiver
BroadcastReceiver是一种用于相应系统范围广播通知的组件。许多广播是由一同发起的–六,通知屏幕已关闭、电池电量不足或以拍摄照片的广播。应用也可以发起广播–例如没通知其他应用某些数据已下载至设备,并且可供其使用。尽管广播接收器不会显示用户界面,但他们可以创建状态通知栏,在发起广播时间时提醒用户。但广播接收器更常见的用途只是作为通向其他组件的“通道”,设计用于执行极少量的工作,例如,他可能会基于时间发起意向服务来执行某项工作。
Android系统设计的独特之处在于,任何应用都可以启动其他应用的组件。例如,如果你想让用户使用设备的相机拍摄照片,很有可能有另一个应用可以执行该操作,那么您的应用就可以利用该应用,而不是开发一个Activity来自行拍摄照片。您不需要继承甚至链接到该相机应用代码,而是只需启动拍摄照片的相机应用中的Activity。完成拍摄时,系统甚至将照片返回您的应用,以便您使用。对用户而言,就好像相机真正是您应用的组成部分。
当系统启动某个组件时,回祁东该应用的进程(如果尚未运行),并实例化该组件所需的类。例如,如果您的应用启动相机应用中拍摄照片的Activity,则该Activity会属于相机应用的进程中运行。因此,与大多数其他系统上的应用不同,Android应用并没有单一入口点(例如,没有main()函数)
由于系统在单独的进程中运行每个应用,且其稳健权限会限制对其他应用的访问,因此您的应用无法直接启动其他应用的组件,但Android系统却可以。因此,想要启动其他应用中的组件,您必须向系统传递一则消息,说明你想启动特定组件的Intent。系统随后便会为您启动该组件。
启动组件
四种组件类型中的三种-Activity、Service和BroadcastReceiver-通过名为Intent的异步消息进行启动。Intent会在运行时将各个组件监护绑定(您可以将Intent视为从其他组将请求操作的信使),无论组件属于您的还是其他应用。
Intent不会启动另一个组件类型-ContentProvider,后者会在成为ContentResolver的请求目标时启动。内容解析程序通过ContentProvider处理所有直接事务,使得通过提供程序执行事务的组件可以无需执行事务,而是改为在ContentResolver对象上调用方法,这会在内容提供者与请求信息的组件之间流出一个抽象层(以确保安全)。
每种类型的组件有不同的启动方法:
- 您可以通过Intent传递到startActivity()或startActivityForResult()(当您想让Activity返回结构时)来启动Activity(或为其安排新任务)。
- 您可以通过Intent传递到startService()来启动服务(或对执行中的服务下达新指令)。或者您也可以通过Intent传递到bingService()来绑定到该服务。
- 您可以通过将Intent传递到sendBroadcast()、sendOrderedBroadcast()或sendStickyBroadcast()等方式来发起广播。
- 您可以通过在ContentResolver上调用query()来对内容提供者执行查询。
清单文件
在Android系统启动应用组件之前,系统必须通过读取应用的AndroidManifest.xml文件(“清单”文件)确认组件存在。您的应用必须在此文件中声明其所有组件,该文件必须位域应用修昂木的根目录中。
除了声明应用的组件外,清单文件还有许多其他作用,如:
- 确定应用需要的任何用户权限,如互联网访问权限或yoghurt联系人读取权限
- 根据应用使用的API,声明应用所需的最低API级别
- 声明应用使用或需要的硬件和软件功能,如相机、蓝牙服务或多点触摸屏幕
- 应用需要链接的API库(Android框架API除外),如Google地图库
其他功能
您必须通过以下方式声明应用组件Activit的元素
- 服务的元素
- 广播接受者的元素
- 内容提供程序元素
未在清单文件中声明的Activity、Service和ContentProvider对系统不可见,也永远不会运行。不过,广播接收器可以在清单文件中声明或在代码中动态创建(如BroadcastReceiver对象)并通过调用registerReceiver()在系统中注册。
声明应用资源
基于Android系统的设备多种多样,并非所有沈北都提供相同的特性和功能。为防止将您的应用安装在缺少应用所需特性的设备上,您必须通过在清单文件中设备和软件要求,为您的应用支持的设备类型明确定义一个配置文件。其中的大多数声明只是为了提供信息,系统不会读取它们,但Google Play等外部服务会读取它们,以便当用户在设备中搜索时为用户提供过滤功能。