Activity
Activity是与用户交互的入口点,它表示拥有界面的单个屏幕。
有助于完成系统和应用程序之间的以下重要交互:
1、追踪用户当前关心的内容(屏幕上显示的内容),以确保系统继续运行托管的Activity的进程。
2、了解先前使用的进程包含用户可能返回的内容(已停止的Activity),从而更优先保留这些进程。
3、帮助应用处理终止其进程的情况,以便用户可以返回已恢复其先前状态的Activity。
4、提供一种途径,让应用实现彼此之间的用户流,并让系统协调这些用户流。(例:共享)
Activity 作为 Activity 类的子类实现。
服务
服务是一个通用入口点,用于因各种原因使应用在后台保持运行状态。它是一种在后台运行的组件,用于执行长时间运行的操作或作为远程进程执行作业。服务不提供界面。
服务作为 Service 的子类实现
广播接收器
借助广播接收器组件,系统能够在常规用户流之外向应用传递事件,从而允许应用响应系统范围内的广播通知。由于广播接收器是另一个明确定义的应用入口,因此系统甚至可以向当前未运行的应用传递广播。
广播接收器作为 BroadcastReceiver 的子类实现,并且每条广播都作为Intent对象进行传递。
内容提供程序
内容提供程序管理一组共享的应用数据,可以将这些数据存储在文件系统、SQLite数据库、网络中或者您的应用可访问的任何其它持久化存储位置。其它应用可通过内容提供程序查询或修改数据(如果内容提供程序允许)。
内容提供程序也适用于读取和写入您的应用不共享的私有数据。
内容提供程序作为ContentProvider的子类实现,并且其必须实现一组标准API,以便其他应用能够执行事务。
Android系统设计的独特之处在于,任何应用都可启动其它应用的组件。
例如,当你想让用户使用设备相机拍摄照片时,另一个应用可能也可执行该操作,因而您的应用便可使用该应用,而非自行产生一个Activity来拍摄照片。您无需加入甚至链接到该相机应用的代码。只需启动拍摄照片的相机应用中的Activity即可。系统甚至会将照片返回您的应用,以便您使用。对于用户而言,这就如同相机是您应用的一部分。
当系统启动某个组件时,它会启动该应用的进程(如果尚未运行),并实例化所需的类。
例如,如果您的应用启动相机应用中拍摄照片的Activity,则该Activity会在属于相机应用的进程(而非您的应用进程)中运行。因此,与大多数其它系统上的应用不同,Android因并没有单个入口点(即没有main()函数)。
由于系统在单独的进程中运行每个应用,且其文件权限会限制对其它应用的访问,因此您的应用无法直接启动其它应用中的组件,但Android系统可以。**如要启动其它应用中的组件,请向系统传递一条消息,说明启动特定组件的Intent。**系统随后便会为您启动该组件。
启动组件
在四种组件类型中,有三种(Activity、服务和广播接收器)均通过异步消息Intent进行启动。Intent会在运行时对各个组件进行互相绑定。您可以将Intent视为其它组件(无论该组件是属于您的应用还是其它应用)请求操作的信使。
您需要使用Intent对象创建Intent,该对象通过定义消息来启动特定组件(显示Intent)或特定的组件类型(隐式Intent)。
对于Activity和服务,Intent会定义要执行的操作(例如,查看或发送某些内容),并且可指定待操作数据的URL,以及正在启动的组件可能需要了解的信息。
对于广播接收器,Intent只会定义待广播的通知。例如,指示设备电池电量不足的广播指包含指示“电池电量不足”的已知操作字符串。
与Activity、服务和广播接收器不同,内容提供程序并非由Intent启动。相反,它们会在成为ContentResolver的请求目标时启动。内容解析程序会通过内容提供程序处理所有直接事物,因此通过提供程序执行事务的组件便无需执行事物,而是改为在ContentResolver对象上调用方法。这会在内容提供程序与请求信息的组件之间留出一个抽象层(以确保安全)。
每种组件都有不同的启动方法:
- 如要启动Activity,您可以向startActivity()或startActivityForResult()传递Intent(当您想让Activity返回结果时),或者为其安排新任务。
- 在Android5.0(API级别21)及更高版本中,您可以使用JobScheduler类来调度操作。对于早期Android版本,您可以通过向startService()传递Intent来启动服务(或对执行中的服务下达新指令)。您也可以通过向将bindService()传递Intent来绑定到该服务。
- 您可以通过向sendBroadcast()、sendOredereBroadcast()或sendStickyBroadcast()等方法传递Intent来发起广播。
- 您可以通过在ContentResolover上调用query(),对内容提供程序执行查询。
清单文件
在Android系统启动应用组件之前,系统必须通过读取应用的清单文件(AndroidMainfest.xml)确认组件存在。您的应用必须在此文件中声明其所有组件,改文件必须位于应用项目目录的根目录中。
除了声明应用组件外,清单文件还有许多其他作用,如:
1、确定应用需要的任何用户权限,如互联网访问权限或对用户联系人的读取权限。
2、根据应用使用的API,声明应用所需的最低API级别。
3、声明应用使用或需要的硬件和软件功能,如相机、蓝牙服务或多点触摸屏幕。
4、声明应用需要链接的API库(Android框架API除外),如Goog了地图库。
声明组件
清单文件的主要任务是告知系统应用组件的相关信息。例如,清单文件可按如下所示声明Activity:
<?xml version="1.0" encoding="utf-8"?>
<manifest ... >
<application android:icon="@drawable/app_icon.png" ... >
<activity android:name="com.example.project.ExampleActivity"
android:label="@string/example_label" ... >
</activity>
...
</application>
</manifest>
在元素中,android:icon属性指向标识应用的图标所对应的资源。
在元素中,android:name属性指定Activity子类的完全限定类名,android:label属性指定用作Activity的用户可见标签的字符串。
您必须使用以下元素声明所有英语组件:
- Activity的元素。
- 服务的元素。
- 广播接收器的元素。
- 内容提供程序的元素。
如果未在清单文件中声明源代码中所包含的Activity、服务和内容提供程序,则这些组件对系统不可见,因此也永远不会运行。不过,您可以通过BroadcastReceiver对象的形式,在清单中声明或代码中动态创建广播接收器;以及通过调用registerReceiver(),在系统中注册广播接收器。
声明组件功能
在应用的清单文件中声明Activity时,您可以选择性地加入声明Activity功能的Intent过滤器,以便响应来自其它应用的Intent。您可以将元素作为组件声明元素的子项进行添加,从而为您的组件声明Intent过滤器。
例如:如果您构建的电子邮件应用包含用于撰写新电子邮件的Activity,则可以通过Intent过滤器来响应“send”Intent(目的是发送新电子邮件),如下方示例所示:
<manifest ... >
...
<application ... >
<activity android:name="com.example.project.ComposeEmailActivity">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<data android:type="*/*" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
</manifest>
如果另一个应用创建ACTION_SEND操作的Intent并将其传递到startActivity(),则系统可能会启动您的Activity,以便用户能够草拟并发送电子邮件。
注意:
如果您使用 Intent 来启动 Service,请使用显式 Intent 来确保应用的安全性。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService(),系统会抛出异常。请勿为您的服务声明 Intent 过滤器。