阅读(4694) (0)

鸿蒙OS Intent

2020-09-16 16:38:39 更新

基本概念

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 中的其他属性来启动应用。

根据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);
}

 
@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
    switch (requestCode) {
        case REQ_CODE_QUERY_WEATHER:
            // Do something with result.
            ...
            return;
        default:
            ...
    }
}

处理方

  1. 作为处理请求的对象,首先需要在配置文件中声明对外提供的能力,以便系统据此找到自身并作为候选的请求处理者。

   {
       "module": {
           ...
           "abilities": [
               {
                   ...
                   "skills":[
                       {
                           "actions":[
                               "ability.intent.QUERY_WEATHER"
                           ]
                       }
                   ]
                   ...
               }
           ]
           ...
       }
       ...
   }

  1. 在 Ability 中配置路由以便支持以此 action 导航到对应的 AbilitySlice。

   @Override
   protected void onStart(Intent intent) {
       ...
       addActionRoute(Intent.ACTION_QUERY_WEATHER, DemoSlice.class.getName());
       ...
   }

  1. 在 Ability 中处理请求,并调用 setResult()方法暂存返回结果。

   @Override
   protected void onActive() {
       ...
       Intent resultIntent = new Intent();
       setResult(0, resultIntent);
       ...
   }