Page 和Ability之间区别

Ability 是应用所具备能力的抽象,也是应用程序的重要组成部分。一个应用可以具备多种能力(即可以包含多个 Ability),HarmonyOS 支持应用以 Ability 为单位进行部署。Ability 可以分为 FA( Feature Ability )和 PA( Particle Ability )两种类型,每种类型为开发者提供了不同的模板,以便实现不同的业务功能。

FA 支持 Page Ability: Page 模板是FA唯一支持的模板,用于提供与用户交互的能力。一个 Page 实例可以包含一组相关页面,每个页面用一个 AbilitySlice 实例表示。

PA支持 Service Ability 和 Data Ability:
1、Service 模板:用于提供后台运行任务的能力。
2、Data 模板:用于对外部提供统一的数据访问抽象。
在配置文件(config.json)中注册 Ability 时,可以通过配置 Ability 元素中的“type”属性来指定 Ability 模板类型,示例如下。

其中,“type”的取值可以为“page”、“service”或“data”,分别代表 Page 模板、Service 模板、Data 模板。为了便于表述,后文中我们将基于 Page 模板、Service 模板、Data 模板实现的 Ability 分别简称为 Page、Service、Data。

{
    "module": {
        ...
        "abilities": [
            {
                ...
                "type": "page"
                ...
            }
        ]
        ...
    }
    ...
}

Page 模板(以下简称“Page”)是 FA 唯一支持的模板,用于提供与用户交互的能力。一个 Page 可以由一个或多个 AbilitySlice 构成,AbilitySlice 是指应用的单个页面及其控制逻辑的总和。

Page和AbilitySlice相当于android的Activity和fragment之间的关系一样。

鸿蒙系统支持不同 Page 之间的跳转,并可以指定跳转到目标 Page 中某个具体的 AbilitySlice。

Page 和Ability之间区别_第1张图片

AbilitySlice 路由配置:

Page 进入前台时界面默认只展示一个 AbilitySlice,

默认展示的 AbilitySlice 是通过setMainRoute()方法来指定的。如果需要更改默认展示的 AbilitySlice,可以通过addActionRoute()方法为此 AbilitySlice 配置一条路由规则。

public class MainAbility extends Ability {
    //启动page的页面
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(MainAbilitySlice.class.getName());

        //add设置路由
        addActionRoute("action.news.list", NewsListSlice.class.getName());
        addActionRoute("action.news.detail", NewsDetailSlice.class.getName());
    }

    
}

addActionRoute() 方法中使用的动作命名,需要在应用配置文件(config.json)中注册:

{
    "module": {
        "abilities": [
            {
                "skills":[
                    {
                        "actions":[
                            "action.news.list",
                            "action.news.detail"
                        ]
                    }
                ]
                ...
            }
        ]
        ...
    }
    ...
}

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

同一Page内实现跳转:(present关键词)

@Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        initComponents();
    }

    private void initComponents() {
        Button button = (Button) findComponentById(ResourceTable.Id_button);
        
        button.setClickedListener(listener -> present(new SecondAbilitySlice(), new Intent()));
       
    }

跳转处理返回值:

1、用户从导航目标 AbilitySlice 返回时,能够获得其返回结果,则应当使用 presentForResult() 实现导航。系统将回调 onResult() 来接收和处理返回结果,开发者需要重写该方法。返回结果由导航目标 AbilitySlice 在其生命周期内通过 setResult() 进行设置。

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:
            ...
    }
}

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

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

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

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

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

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

 

注意:系统为每个 Page 维护了一个 AbilitySlice 实例的栈,每个进入前台的 AbilitySlice 实例均会入栈。当开发者在调用 present( )或 presentForResult() 时指定的 AbilitySlice 实例已经在栈中存在时,则栈中位于此实例之上的 AbilitySlice 均会出栈并终止其生命周期。前面的示例代码中,导航时指定的 AbilitySlice 实例均是新建的,即便重复执行此代码(此时作为导航目标的这些实例是同一个类),也不会导致任何 AbilitySlice 出栈。

不同 Page 之间跳转:

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);

 

 

 

你可能感兴趣的:(【鸿蒙OS】)