鸿蒙Harmony和Android的Intent对比
鸿蒙harmony和android都有Intent,用于一个操作界面调用另一个操作界面,并可用于传递数据。
Harmony Intent:
Intent是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。Intent的构成元素包括Operation与Parameters,具体描述参见表1。
属性 | 子属性 | 描述 |
---|---|---|
Operation | Action | 表示动作,通常使用系统预置Action,应用也可以自定义Action。例如IntentConstants.ACTION_HOME表示返回桌面动作。 |
Entity | 表示类别,通常使用系统预置Entity,应用也可以自定义Entity。例如Intent.ENTITY_HOME表示在桌面显示图标。 | |
Uri | 表示Uri描述。如果在Intent中指定了Uri,则Intent将匹配指定的Uri信息,包括scheme, schemeSpecificPart, authority和path信息。 | |
Flags | 表示处理Intent的方式。例如Intent.FLAG_ABILITY_CONTINUATION标记在本地的一个Ability是否可以迁移到远端设备继续运行。 | |
BundleName | 表示包描述。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。 | |
AbilityName | 表示待启动的Ability名称。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。 | |
DeviceId | 表示运行指定Ability的设备ID。 | |
Parameters | – | Parameters是一种支持自定义的数据结构,开发者可以通过Parameters传递某些请求所需的额外信息。 |
当Intent用于发起请求时,根据指定元素的不同,分为两种类型:
- 如果同时指定了BundleName与AbilityName,则根据Ability的全称(例如“com.demoapp.FooAbility”)来直接启动应用。
- 如果未同时指定BundleName和AbilityName,则根据Operation中的其他属性来启动应用。
说明
Intent设置属性时,必须先使用Operation来设置属性。如果需要新增或修改属性,必须在设置Operation后再执行操作。
关于Intent最简单的使用方法,可参见快速入门的示例代码。其中“实现页面跳转”重点描述了使用Intent实现两个页面跳转关系的操作。
根据Ability的全称启动应用
通过构造包含BundleName与AbilityName的Operation对象,可以启动一个Ability、并导航到该Ability。示例代码如下:
Intent intent = new Intent(); // 通过Intent中的OperationBuilder类构造operation对象,指定设备标识(空串表示当前设备)、应用包名、Ability名称Operation operation = new Intent.OperationBuilder() .withDeviceId("") .withBundleName("com.demoapp") .withAbilityName("com.demoapp.FooAbility") .build(); // 把operation设置到intent中intent.setOperation(operation);startAbility(intent);
作为处理请求的对象,会在相应的回调方法中接收请求方传递的Intent对象。以导航到另一个Ability为例,导航的目标Ability可以在其onStart()回调的参数中获得Intent对象。
根据Operation的其他属性启动应用
有些场景下,开发者需要在应用中使用其他应用提供的某种能力,而不感知提供该能力的具体是哪一个应用。例如开发者需要通过浏览器打开一个链接,而不关心用户最终选择哪一个浏览器应用,则可以通过Operation的其他属性(除BundleName与AbilityName之外的属性)描述需要的能力。如果设备上存在多个应用提供同种能力,系统则弹出候选列表,由用户选择由哪个应用处理请求。以下示例展示使用Intent跨Ability查询天气信息。
请求方
在Ability中构造Intent以及包含Action的Operation对象,并调用startAbilityForResult()方法发起请求。然后重写onAbilityResult()回调方法,对请求结果进行处理。
private void queryWeather() { Intent intent = new Intent(); Operation operation = new Intent.OperationBuilder() .withAction(Intent.ACTION_QUERY_WEATHER) .build(); intent.setOperation(operation); startAbilityForResult(intent, REQ_CODE_QUERY_WEATHER);} @Overrideprotected void onAbilityResult(int requestCode, int resultCode, Intent resultData) { switch (requestCode) { case REQ_CODE_QUERY_WEATHER: // Do something with result. ... return; default: ... }}
处理方
- 作为处理请求的对象,首先需要在配置文件中声明对外提供的能力,以便系统据此找到自身并作为候选的请求处理者。
- {
- “module”: {
- …
- “abilities”: [
- {
- …
- “skills”:[
- {
- “actions”:[
- “ability.intent.QUERY_WEATHER”
- ]
- }
- ]
- …
- }
- ]
- …
- }
- …
- }
- 在Ability中配置路由以便支持以此action导航到对应的AbilitySlice。
- @Override
- protected void onStart(Intent intent) {
- …
- addActionRoute(Intent.ACTION_QUERY_WEATHER, DemoSlice.class.getName());
- …
- }
- 在Ability中处理请求,并调用setResult()方法暂存返回结果。
- @Override
- protected void onActive() {
- …
- Intent resultIntent = new Intent();
- setResult(0, resultIntent); //0为当前Ability销毁后返回的resultCode。
- …
- }
Android Intent:
Intent
是一个消息传递对象,您可以用来从其他应用组件请求操作。尽管 Intent 可以通过多种方式促进组件之间的通信,但其基本用例主要包括以下三个:
- 启动 Activity
Activity
表示应用中的一个屏幕。通过将Intent
传递给startActivity()
,您可以启动新的Activity
实例。Intent
用于描述要启动的 Activity,并携带任何必要的数据。如果您希望在 Activity 完成后收到结果,请调用startActivityForResult()
。在 Activity 的onActivityResult()
回调中,您的 Activity 将结果作为单独的Intent
对象接收。如需了解详细信息,请参阅 Activity 指南。 - 启动服务
Service
是一个不使用用户界面而在后台执行操作的组件。使用 Android 5.0(API 级别 21)及更高版本,您可以启动包含JobScheduler
的服务。如需了解有关JobScheduler
的详细信息,请参阅其API-reference documentation
。对于 Android 5.0(API 级别 21)之前的版本,您可以使用Service
类的方法来启动服务。通过将Intent
传递给startService()
,您可以启动服务执行一次性操作(例如,下载文件)。Intent
用于描述要启动的服务,并携带任何必要的数据。如果服务旨在使用客户端-服务器接口,则通过将Intent
传递给bindService()
,您可以从其他组件绑定到此服务。如需了解详细信息,请参阅服务指南。 - 传递广播广播是任何应用均可接收的消息。系统将针对系统事件(例如:系统启动或设备开始充电时)传递各种广播。通过将
Intent
传递给sendBroadcast()
或sendOrderedBroadcast()
,您可以将广播传递给其他应用。
本页的其余部分将说明 Intent 的工作方式及如何使用 Intent。对于相关信息,请参阅与其他应用交互和共享内容。
Intent 类型
Intent 分为两种类型:
- 显式 Intent:通过提供目标应用的软件包名称或完全限定的组件类名来指定可处理 Intent 的应用。通常,您会在自己的应用中使用显式 Intent 来启动组件,这是因为您知道要启动的 Activity 或服务的类名。例如,您可能会启动您应用内的新 Activity 以响应用户操作,或者启动服务以在后台下载文件。
- 隐式 Intent :不会指定特定的组件,而是声明要执行的常规操作,从而允许其他应用中的组件来处理。例如,如需在地图上向用户显示位置,则可以使用隐式 Intent,请求另一具有此功能的应用在地图上显示指定的位置。
图 1 显示如何在启动 Activity 时使用 Intent。当 Intent
对象显式命名某个具体的 Activity 组件时,系统立即启动该组件。

图 1. 隐式 Intent 如何通过系统传递以启动其他 Activity:[1] Activity A 创建包含操作描述的 Intent
,并将其传递给 startActivity()
。[2] Android 系统搜索所有应用中与 Intent 匹配的 Intent 过滤器。找到匹配项之后,[3] 该系统通过调用匹配 Activity (Activity B) 的 onCreate()
方法并将其传递给 Intent
,以此启动匹配 Activity。
使用隐式 Intent 时,Android 系统通过将 Intent 的内容与在设备上其他应用的清单文件中声明的 Intent 过滤器进行比较,从而找到要启动的相应组件。如果 Intent 与 Intent 过滤器匹配,则系统将启动该组件,并向其传递 Intent
对象。如果多个 Intent 过滤器兼容,则系统会显示一个对话框,支持用户选取要使用的应用。
Intent 过滤器是应用清单文件中的一个表达式,用于指定该组件要接收的 Intent 类型。例如,通过为 Activity 声明 Intent 过滤器,您可以使其他应用能够直接使用某一特定类型的 Intent 启动 Activity。同样,如果您没有为 Activity 声明任何 Intent 过滤器,则 Activity 只能通过显式 Intent 启动。
注意:为了确保应用的安全性,启动 Service
时,请始终使用显式 Intent,且不要为服务声明 Intent 过滤器。使用隐式 Intent 启动服务存在安全隐患,因为您无法确定哪些服务将响应 Intent,且用户无法看到哪些服务已启动。从 Android 5.0(API 级别 21)开始,如果使用隐式 Intent 调用 bindService()
,系统会抛出异常。
构建 Intent
Intent
对象携带 Android 系统用来确定要启动哪个组件的信息(例如,准确的组件名称或应当接收该 Intent 的组件类别),以及收件人组件为了正确执行操作而使用的信息(例如,要采取的操作以及要处理的数据)。
Intent
中包含的主要信息如下:组件名称要启动的组件名称。
这是可选项,但也是构建显式 Intent 的一项重要信息,这意味着 Intent 应当仅传递给由组件名称定义的应用组件。如果没有组件名称,则 Intent 则为隐式,且系统将根据其他 Intent 信息(例如,以下所述的操作、数据和类别)决定哪个组件应当接收 Intent。如需在应用中启动特定的组件,则应指定该组件的名称。
请注意:启动 Service
时,应始终指定组件名称。否则,您无法确定哪项服务会响应 Intent,且用户无法看到哪项服务已启动。
Intent
的这一字段是 ComponentName
对象,您可以使用目标组件的完全限定类名指定此对象,其中包括应用的软件包名称。例如,com.example.ExampleActivity
。您可以使用 setComponent()
、setClass()
、setClassName()
,或 Intent
构造函数设置组件名称。操作指定要执行的通用操作(例如,查看或选取)的字符串。
对于广播 Intent,这是指已发生且正在报告的操作。操作会在很大程度上决定其余 Intent 的构成,特别是数据和 extra 中包含的内容。
您可以指定自己的操作,供 Intent 在您的应用内使用(或者供其他应用在您的应用中调用组件)。但是,您通常应该使用由Intent
类或其他框架类定义的操作常量。以下是一些用于启动 Activity 的常见操作:ACTION_VIEW
如果您拥有一些某项 Activity 可向用户显示的信息(例如,要使用图库应用查看的照片;或者要使用地图应用查看的地址),请通过 Intent 将此操作与 startActivity()
结合使用。ACTION_SEND
这也称为共享 Intent。如果您拥有一些用户可通过其他应用(例如,电子邮件应用或社交共享应用)共享的数据,则应使用 Intent 将此操作与 startActivity()
结合使用。
有关更多定义通用操作的常量,请参阅 Intent
类参考文档。其他操作在 Android 框架中的其他位置定义。例如,对于在系统的设置应用中打开特定屏幕的操作,将在 Settings
中定义。
您可以使用 setAction()
或 Intent
构造函数为 Intent 指定操作。