鸿蒙Ability(一):Feature Ability的Page Ability模板

鸿蒙Ability

导语

在鸿蒙应用中在创建一个Page Ability(Feature Ability)时(Page Ability可以理解为安卓的Acitvity),会生成两个类:“XxxAbility”和“XxxAbilitySlice”,和一个布局文件“ability_Xxx.xml”。
鸿蒙Ability(一):Feature Ability的Page Ability模板
鸿蒙Ability(一):Feature Ability的Page Ability模板
为什么创建Ability的时候,会有三个选项呢?还会自动生成AbilitySlice呢?
这就涉及到鸿蒙中一个很重要的概念——Ability

Ability概念

Ability是应用的重要组成部分,是应用所具备能力的抽象。一个应用可以具备多种能力(即可以包含多个Ability)。Ability可以分为FA(Feature Ability)和PA(Particle Ability)两种类型。
①Feature Ability
FA代表有界面的Ability,支持Page Ability模板(是FA唯一支持的模板),用于提供与用户交互的能力。
②Particle Ability
PA代表*面的Ability,支持Service Ability和Data Ability模板。
Service模板用于提供后台运行任务的能力,
Data模板用于对外部提供统一的数据访问抽象。
在配置文件config.json中注册Ability时,可以通过配置Ability元素中的“type”属性来指定Ability模板类型。
“type”的取值可以为“page”(代表Page模板)、“service”(代表Service模板)或“data”(代表Data模板)。
鸿蒙Ability(一):Feature Ability的Page Ability模板

Feature Ability

Page与AbilitySlice

Page模板是Feature Ability唯一支持的模板。一个Page实例可以包含一组相关页面,每个页面用一个AbilitySlice实例表示。
在Feature Ability中,有一个很重要的概念就是AbilitySlice,一个Feature Ability可以由一个或多个AbilitySlice构成。
AbilitySlice是Feature Ability的组成单元,是指应用的单个可视化界面及其交互逻辑的总和。一个Feature Ability可以包含一组业务关系密切的可视化界面,每一个可视化界面对应一个AbilitySlice。
可以这么说:Feature Ability本质上就是一个页面,可以称为Page Ability(后文将称Feature Ability为Page Ability),这里的Page可以理解为Android中的Activity,Abilityslice可以理解为Android中的Layout。
Ability可以有界面(如Feature Ability),也可以没有界面(如Particle Ability)
有界面要显示时,在Ability中,通过setMainRoute关联要显示的AbilitySlice(XxxAbility通过SetMainRoute关联XxxAbilitySlice
设置布局文件、处理业务逻辑的代码写在AbilitySlice中(和布局文件ability_xxx.xml关联的是XxxAbilitySlice

在Page Ability中用代码编写界面

public class CodeWritePageAbilitySlice extends AbilitySlice {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        //super.setUIContent(ResourceTable.Layout_ability_code_write_page);

        // 使用代码生成 UI 布局与组件

        // 声明布局 创建相对布局, 传入当前界面 Ability 对象
        DirectionalLayout directionalLayout = new DirectionalLayout(this);
        // 设置布局大小
        directionalLayout.setWidth(MATCH_PARENT);
        directionalLayout.setHeight(MATCH_PARENT);
//        // 创建布局配置对象DirectionalLayout.LayoutConfig
//        // 构造函数中传入宽高设置
//        DirectionalLayout.LayoutConfig layoutConfig = new DirectionalLayout.LayoutConfig(
//                DirectionalLayout.LayoutConfig.MATCH_PARENT,
//                DirectionalLayout.LayoutConfig.MATCH_PARENT);
//        // 将布局配置对象设置给布局对象
//        directionalLayout.setLayoutConfig(layoutConfig);
        // 设置水平方向
        directionalLayout.setOrientation(Component.HORIZONTAL);

        // 设置布局背景为淡蓝色
        // 创建背景元素
        ShapeElement shapeElement = new ShapeElement();
        // 设置淡蓝色
        shapeElement.setRgbColor(new RgbColor(187, 255, 255));
        // 设置页面背景颜色(将背景设置给布局)
        directionalLayout.setBackground(shapeElement);

        // 创建一个Text文本组件
        Text text = new Text(this);
        // 设置文本的布局
        // 创建布局配置对象DependentLayout.LayoutConfig
        // 在构造函数中传入宽高设置,这里设置成宽800、高自适应
        DependentLayout.LayoutConfig textLayoutConfig = new DependentLayout.LayoutConfig(
                800,  DependentLayout.LayoutConfig.MATCH_CONTENT);
        //设置margin
        textLayoutConfig.setMargins(100, 100, 100, 100);
        // 将布局配置对象设置给布局对象(为组件添加对应布局的布局属性)
        text.setLayoutConfig(textLayoutConfig);

        // 设置text布局背景为淡紫色
        // 创建背景元素
        ShapeElement shapeElementText = new ShapeElement();
        // 设置淡紫色
        shapeElementText.setRgbColor(new RgbColor(230, 230, 250));
        // 将背景设置给布局 设置页面背景颜色
        text.setBackground(shapeElementText);

        // 设置显示的文本
        text.setText("Hi there");
        // 设置文字颜色
        text.setTextColor(Color.BLACK);
        //text.setTextColor(new Color(0xFF258293));
        // 设置文字大小
        text.setTextSize(100);
        // 设置对齐方式 , 居中
        text.setTextAlignment(TextAlignment.CENTER);
        // 将组件添加到布局中
        directionalLayout.addComponent(text);
        
        //将布局作为根布局添加到视图树中
        super.setUIContent(directionalLayout);
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }
}

鸿蒙Ability(一):Feature Ability的Page Ability模板

生命周期

Page Ability生命周期

官方文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-page-lifecycle-0000000000029840#ZH-CN_TOPIC_0000001083455837__fig3655123011010
鸿蒙Ability(一):Feature Ability的Page Ability模板

public class LifeCycleAbility extends Ability {

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "resultValue");

    @Override
    public void onStart(Intent intent) {
        //当系统首次创建Page实例时,触发该回调,该回调在其生命周期过程中仅触发一次。
        //Page在该逻辑后将进入INACTIVE(非激活状态)状态。
        //开发者必须重写该方法,并在此使用setMainRoute配置默认展示的AbilitySlice。
        super.onStart(intent);
        super.setMainRoute(LifeCycleAbilitySlice.class.getName());
        HiLog.info(LABEL, "LifeCycleAbility.onStart");
    }


    @Override
    protected void onActive() {
        //该状态是应用与用户交互的状态
        // (进入前台时触发)
        super.onActive();
        HiLog.info(LABEL, "LifeCycleAbility.onActive");
    }

    @Override
    protected void onInactive() {
        //开发者应该在此回调中实现Page失去焦点时应表现的恰当行为,如释放资源
        //(失去焦点时触发)
        super.onInactive();
        HiLog.info(LABEL, "LifeCycleAbility.onInactive");
    }

    @Override
    protected void onBackground() {
        //开发者应该在此回调中释放Page不可见时无用的资源
        //或在此回调中执行较为耗时的状态保存操作
        //(不可见时触发)
        super.onBackground();
        HiLog.info(LABEL, "LifeCycleAbility.onBackground");
    }

    @Override
    protected void onForeground(Intent intent) {
        //开发者应当在此回调中重新申请在onBackground()中释放的资源
        //(重新进入可见状态时触发)
        super.onForeground(intent);
        HiLog.info(LABEL, "LifeCycleAbility.onForeground");
    }

    @Override
    protected void onStop() {
        //系统将要销毁Page时,将会触发此回调函数,通知用户进行系统资源的释放
        //(销毁Ability时触发)
        super.onStop();
        HiLog.info(LABEL, "LifeCycleAbility.onStop");
    }
}

注意
onStart()在整个生命周期过程中仅触发一次,而onActive()在每一次从后台回到前台的时候都会被调用,所以在开发中,把只需要加载一次的资源放在onStart()中,把要实时变更的资源放在onActive()中。
开发者通常需要成对实现onActive()和onInactive(),在onActive()中获取在onInactive()中被释放的资源。

AbilitySlice生命周期

AbilitySlice作为Page Ability的组成单元,其生命周期是依托于其所属Page Ability生命周期的。
AbilitySlice和Page Ability具有相同的生命周期状态和同名的回调,当Page Ability生命周期发生变化时,它的AbilitySlice也会发生相同的生命周期变化。
此外,AbilitySlice还具有独立于Page Ability的生命周期变化,这发生在同一Page Ability中的AbilitySlice之间导航时,此时Page Ability的生命周期状态不会改变,AbilitySlice生命周期回调与Page Ability的相应回调类似。当Page Ability被系统销毁时,其所有已实例化的AbilitySlice将联动销毁,而不仅是处于前台的AbilitySlice。

public class LifeCycleAbilitySlice extends AbilitySlice {

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "resultValue");

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        //由于AbilitySlice承载具体的页面,开发者必须重写AbilitySlice的onStart()回调,并在此方法中通过setUIContent()方法设置页面
        super.setUIContent(ResourceTable.Layout_ability_life_cycle);
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onStart");
    }

    @Override
    public void onActive() {
        super.onActive();
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onActive");
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onForeground");
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onBackground");
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onInactive");
    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(LABEL, "LifeCycleAbilitySlice.onStop");
    }
}

生命周期示例

生命周期示例之同一Page跳转

在LifeCycleAbilitySlice的onStart()中增加按钮跳转到LifeCycleSecondAbilitySlice

		//生命周期示例之同一Page跳转
        Button button = (Button) findComponentById(ResourceTable.Id_button);
        // 为按钮设置点击回调
        button.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                present(new LifeCycleSecondAbilitySlice(), new Intent());
            }
        });

LifeCycleSecondAbilitySlice.java的代码如下:

/**
 * 生命周期测试AbilitySlice
 *
 * @author 舒小羽
 * @date 2021/4/15 0015
 */
public class LifeCycleSecondAbilitySlice extends AbilitySlice {

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "resultValue");

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onStart");

        // 声明布局 创建相对布局, 传入当前界面 Ability 对象
        DependentLayout dependentLayout = new DependentLayout(this);
        // 创建布局配置对象DependentLayout.LayoutConfig
        // 构造函数中传入宽高设置
        DependentLayout.LayoutConfig layoutConfig = new DependentLayout.LayoutConfig(
                DependentLayout.LayoutConfig.MATCH_PARENT,
                DependentLayout.LayoutConfig.MATCH_PARENT);
        // 将布局配置对象设置给布局对象
        dependentLayout.setLayoutConfig(layoutConfig);

        // 设置布局背景为粉红色
        // 创建背景元素
        ShapeElement shapeElement = new ShapeElement();
        // 设置粉红色
        shapeElement.setRgbColor(new RgbColor(255, 130, 171));
        // 设置页面背景颜色(将背景设置给布局)
        dependentLayout.setBackground(shapeElement);

        // 创建一个Text文本组件
        Text text = new Text(this);
        // 设置文本的布局
        text.setWidth(MATCH_CONTENT);
        // 设置显示的文本
        text.setText("同一个Page的跳转");
        // 设置文字颜色
        text.setTextColor(Color.BLACK);
        // 设置文字大小
        text.setTextSize(100);
        // 将组件添加到布局中
        dependentLayout.addComponent(text);

        //将布局作为根布局添加到视图树中
        super.setUIContent(dependentLayout);
    }

    @Override
    public void onActive() {
        super.onActive();
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onActive");
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onForeground");
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onBackground");
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onInactive");
    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(LABEL, "LifeCycleSecondAbilitySlice.onStop");
    }
}

运行代码。。。。。。。。。。。。。。。。。。。。。。。。。
首先启动LifeCycleAbility的是LifeCycleAbilitySlice,生命周期的调用顺序为:
LifeCycleAbility.onStart–>LifeCycleAbilitySlice.onStart–>LifeCycleAbility.onActive–>LifeCycleAbilitySlice.onActive
可以看出AbilitySlice作为Page Ability的组成单元,其生命周期是依托于其所属Page Ability生命周期的。 AbilitySlice和Page Ability具有相同的生命周期状态和同名的回调,当Page Ability生命周期发生变化时,它的AbilitySlice也会发生相同的生命周期变化。
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleAbility.onStart
resultValue: LifeCycleAbilitySlice.onStart
resultValue: LifeCycleAbility.onActive
resultValue: LifeCycleAbilitySlice.onActive

当点击LifeCycleAbilitySlice中的按钮跳转到LifeCycleAbility的LifeCycleSecondAbilitySlice,生命周期的调用顺序为:
LifeCycleAbilitySlice.onInactive–>LifeCycleSecondAbilitySlice.onStart–>LifeCycleSecondAbilitySlice.onActive–>LifeCycleAbilitySlice.onBackground
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleAbilitySlice.onInactive
resultValue: LifeCycleSecondAbilitySlice.onStart
resultValue: LifeCycleSecondAbilitySlice.onActive
resultValue: LifeCycleAbilitySlice.onBackground

当点击返回按钮,从LifeCycleSecondAbilitySlice返回到LifeCycleAbilitySlice,生命周期的调用顺序为:
LifeCycleSecondAbilitySlice.onInactive–>LifeCycleAbilitySlice.onForeground–>LifeCycleAbilitySlice.onActive–>LifeCycleSecondAbilitySlice.onBackground–>LifeCycleSecondAbilitySlice.onStop
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleSecondAbilitySlice.onInactive
resultValue: LifeCycleAbilitySlice.onForeground
resultValue: LifeCycleAbilitySlice.onActive
resultValue: LifeCycleSecondAbilitySlice.onBackground
resultValue: LifeCycleSecondAbilitySlice.onStop

同一Page中的AbilitySlice之间导航,Page的生命周期状态不会改变。在这个流程中,MainAbility始终处于活跃状态。
当点击手机Home键的时候,生命周期的调用顺序为:
LifeCycleAbility.onInactive–>LifeCycleAbilitySlice.onInactive–>LifeCycleAbility.onBackground–>LifeCycleAbilitySlice.onBackground
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleAbility.onInactive
resultValue: LifeCycleAbilitySlice.onInactive
resultValue: LifeCycleAbility.onBackground
resultValue: LifeCycleAbilitySlice.onBackground

生命周期示例之不同Page跳转

在LifeCycleAbilitySlice的onStart()中增加按钮跳转到LifeCycleDifferentPageAbility

 //生命周期示例之不同Page跳转
 Button button1 = (Button) findComponentById(ResourceTable.Id_button1);
        // 为按钮设置点击回调
        button1.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                Intent intent = new Intent();
                Operation operation = new Intent.OperationBuilder()
                        .withDeviceId("")
                        .withBundleName("org.example.harmonypageabilitydemo")
                        .withAbilityName(".LifeCycleDifferentPageAbility")
                        .build();
                intent.setOperation(operation);
                startAbility(intent);
            }
        });

LifeCycleDifferentPageAbility.java的代码如下:

public class LifeCycleDifferentPageAbility extends Ability {

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "resultValue");

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setMainRoute(LifeCycleDifferentPageAbilitySlice.class.getName());
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onStart");
    }

    @Override
    protected void onActive() {
        super.onActive();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onActive");
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onInactive");
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onBackground");
    }

    @Override
    protected void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onForeground");
    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbility.onStop");
    }
}

LifeCycleDifferentPageAbilitySlice.java的代码如下:

public class LifeCycleDifferentPageAbilitySlice extends AbilitySlice {

    private static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "resultValue");

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_life_cycle_different_page);
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onStart");
    }

    @Override
    public void onActive() {
        super.onActive();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onActive");
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onForeground");
    }

    @Override
    protected void onBackground() {
        super.onBackground();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onBackground");
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onInactive");
    }

    @Override
    protected void onStop() {
        super.onStop();
        HiLog.info(LABEL, "LifeCycleDifferentPageAbilitySlice.onStop");
    }
}

运行代码。。。。。。。。。。。。。。。。。。。。。。。。。
可以看见,从LifeCycleAbility跳转到LifeCycleDifferentPageAbility,
LifeCycleAbility和LifeCycleAbilitySlice首先都失去焦点,调用了onInactive,接着,LifeCycleDifferentPageAbility与LifeCycleDifferentPageAbilitySlice启动,调用了onStart,然后一起进入了前台,调用了onActive,最后,LifeCycleAbility与LifeCycleAbilitySlice都不可见了,调用了onBackground。
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleAbility.onInactive
resultValue: LifeCycleAbilitySlice.onInactive
resultValue: LifeCycleDifferentPageAbility.onStart
resultValue: LifeCycleDifferentPageAbilitySlice.onStart
resultValue: LifeCycleDifferentPageAbility.onActive
resultValue: LifeCycleDifferentPageAbilitySlice.onActive
resultValue: LifeCycleAbility.onBackground
resultValue: LifeCycleAbilitySlice.onBackground

当点击了返回按钮后
从LifeCycleDifferentPageAbility回到LifeCycleAbility
先是LifeCycleDifferentPageAbility与LifeCycleDifferentPageAbilitySlice失去焦点触发onInactive,其次是LifeCycleAbility与LifeCycleAbilitySlice重新进入可见触发onForeground,再是LifeCycleAbility与LifeCycleAbilitySlice进入前台触发onActive,然后是LifeCycleDifferentPageAbility与LifeCycleDifferentPageAbilitySlice不可见触发onBackground,最后LifeCycleDifferentPageAbility与LifeCycleDifferentPageAbilitySlice销毁触发onStop。
鸿蒙Ability(一):Feature Ability的Page Ability模板

resultValue: LifeCycleDifferentPageAbility.onInactive
resultValue: LifeCycleDifferentPageAbilitySlice.onInactive
resultValue: LifeCycleAbility.onForeground
resultValue: LifeCycleAbilitySlice.onForeground
resultValue: LifeCycleAbility.onActive
resultValue: LifeCycleAbilitySlice.onActive
resultValue: LifeCycleDifferentPageAbility.onBackground
resultValue: LifeCycleDifferentPageAbilitySlice.onBackground
resultValue: LifeCycleDifferentPageAbility.onStop
resultValue: LifeCycleDifferentPageAbilitySlice.onStop

AbilitySlice间的导航

同一Page内导航(同一Page页面的AbilitySlice间的导航)
不同Page间导航(不同Page页面的AbilitySlice间的导航(跨Pgae页面))

AbilitySlice路由配置

虽然一个Page Ability可以由一个或多个AbilitySlice构成,但是Page进入前台时界面默认只展示一个AbilitySlice。默认展示的AbilitySlice是通过setMainRoute()方法来指定的。
如果需要更改默认展示的AbilitySlice,可以通过
addActionRoute()
方法为此AbilitySlice配置一条路由规则,当其他Page实例期望导航到此AbilitySlice时,可以在Intent中指定Action。配置了新的路由规则后,需要在配置文件中将其声明,否则会找不到。
setMainRoute()方法与addActionRoute()方法使用示例如下:

public class MainAbility extends Ability {
    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        //设置默认展示的AbilitySlice
        super.setMainRoute(MainAbilitySlice.class.getName());
        
        //set the action route
        //设置路由规则,应用于不同page的导航
        addActionRoute("action.second", SecondAbilitySlice.class.getName());
    }
}

就是说,"action.second"这个action值匹配的是SecondAbilitySlice这个slice,当需要跳转到SecondAbilitySlice这个slice的时候,通过指定"action.second"这个action值跳转到slice。
在配置文件中声明配置的新的路由规则示例如下:
鸿蒙Ability(一):Feature Ability的Page Ability模板

同一Page内导航

跳转不携带数据

		Button button = (Button) findComponentById(ResourceTable.Id_button);
        // 为按钮设置点击回调
        button.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                //第一种导航方式,跳转到同一page内不携带数据
                //参数1:需要导航去的页面,参数2:Intent对象
                present(new SamePageSlice(), new Intent());
            }
        });

跳转并携带数据

 		Button button2 = (Button) findComponentById(ResourceTable.Id_button2);
        // 为按钮设置点击回调
        button2.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                //第二种导航方式,跳转到同一page内并携带数据
                Intent intent1 = new Intent();
                intent1.setParam("name", "yu");
                present(new SamePageSlice(), intent1);
            }
        });

接收携带的数据(如果携带了参数跳转,如何获取到传递的参数呢?)
Intent作为处理请求的对象,会在相应的回调方法中接收请求方传递的Intent对象,导航的目标可以在其onStart()回调的参数中获得Intent对象。
需要跳转过去的Slice的onStart()方法的参数就是一个Intent,因此可以直接通过此Intent去获取传递过去的参数。
鸿蒙Ability(一):Feature Ability的Page Ability模板

		//第二种导航方式,跳转到同一page内并携带数据
        //接收携带的数据
        Text text = (Text) findComponentById(ResourceTable.Id_text);
        if (intent != null) {
            text.setText("接收到的数据name=" + intent.getStringParam("name"));
        }

跳转并返回数据

如果开发者希望在用户从导航目标AbilitySlice返回时,能够获得其返回结果,则应当使用presentForResult()实现导航。用户从导航目标AbilitySlice返回时,系统将回调onResult()来接收和处理返回结果,开发者需要重写该方法。

 		text = (Text) findComponentById(ResourceTable.Id_text);
        Button button3 = (Button) findComponentById(ResourceTable.Id_button3);
        // 为按钮设置点击回调
        button3.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                //第三种导航方式,跳转到同一page内并返回数据
                //参数1:需要导航去的页面,参数2:Intent对象,参数3:请求码
                presentForResult(new SamePageSlice(), new Intent(), 0);
            }
        });

    //第三种导航方式,跳转到同一page内并返回数据
    //接收返回的数据
    @Override
    protected void onResult(int requestCode, Intent resultIntent) {
        super.onResult(requestCode, resultIntent);
        //接收requestCode == 0的返回的数据
        if (requestCode == 0) {
            int id = resultIntent.getIntParam("ID", -1);//-1为默认值,如果没有传回id的话
            text.setText("回传的数据 id=" + id);
        }
    }

返回数据

		//第三种导航方式,跳转到同一page内并返回数据
        //返回数据(按返回键时有效)
        Intent intent1 = new Intent();
        intent1.setParam("ID", 123);
        setResult(intent1);
        //自动返回上一页
        //terminate();

注:
第二种和第三种导航方式可以结合成跳转到同一page内携带数据并返回数据

不同Page间导航

不同Page中的AbilitySlice相互不可见,所以不能通过present()和presentForResult()方法直接导航。AbilitySlice作为Page的内部单元,以Action的形式向外暴露,因此可以通过配置Intent的Action导航到目标AbilitySlice。
Page间的导航可以使用startAbility()或startAbilityForResult()方法,获得返回结果的回调为onAbilityResult()。在Ability中调用setResult()可以设置返回结果。

根据Ability的全称启动应用

		Button button5 = (Button) findComponentById(ResourceTable.Id_button5);
        button5.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                //根据Ability的全称启动应用,通过Intent来跳转
                Intent intent1 = new Intent();
                //指定待启动FA的bundleName和abilityName
                //通过Intent中的OperationBuilder类构造operation对象
                //指定设备标识(空串表示当前设备)、应用包名、Ability名称
                Operation operation = new Intent.OperationBuilder()
                        //设备id(空串表示当前设备)
                        .withDeviceId("")
                        //应用的包名 表示包描述。
                        //如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。
                        //如果未同时指定BundleName和AbilityName,则根据Operation中的其他属性来启动应用。
                        .withBundleName("org.example.harmonypageabilitydemo")
                        //跳转目标的路径名 通常是包名+类名 或者 .+类名
                        //表示待启动的Ability名称。
                        .withAbilityName("org.example.harmonypageabilitydemo.SecondAbility")
                        //.withAbilityName(".SecondAbility")
                        .build();
                //设置操作方式 把operation设置到intent中
                intent1.setOperation(operation);
                //通过AbilitySlice的startAbility接口实现启动另一个页面
                startAbility(intent1);
                //导航的目标Ability可以在其onStart()回调的参数中获得Intent对象
            }
        });

根据Operation的其他属性启动应用

也就是指定另一个page中的AbilitySlice的action值
withAction的值"action.second"已经在前节的AbilitySlice路由配置用配置过了。

Button button4 = (Button) findComponentById(ResourceTable.Id_button4);
        button4.setClickedListener(new Component.ClickedListener() {
            @Override
            public void onClick(Component component) {
                Intent intent1 = new Intent();
                Operation operation = new Intent.OperationBuilder()
                        //指定另一个page中的AbilitySlice的action值
                        .withAction("action.second")
                        .build();
                intent1.setOperation(operation);
                startAbility(intent1);
            }
        });

Intent

提到页面跳转,就不得不提Intent
官方文档:https://developer.harmonyos.com/cn/docs/documentation/doc-guides/ability-intent-0000000000038799
Intent是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。

上一篇:使用Data Ability读取系统设置项


下一篇:config.json元素含义速查