HarmonyOS中Ability生命周期以及Intent意图跳转

Ability

Page模板(以下简称“Page”)是FA唯一支持的模板,用于提供与用户交互的能力。一个Page可以由一个或多个AbilitySlice构成,AbilitySlice是指应用的单个页面及其控制逻辑的总和。当一个Page由多个AbilitySlice共同构成时,这些AbilitySlice页面提供的业务能力应具有高度相关性。

Ability生命周期

Ability一共有onStart、onActive、onInactive、onBackground、onForeground、onStop几个主要方法,从官网给出的生命周期思维导图就可以基本看出来他们之间的关系。
在这里插入图片描述
其中onStart()方法必须重写,因为要设置对应的AbilitySlice。
在这里插入图片描述

在这里插入图片描述

AbilitySlice

在HarmonyOS应用中,每一个Page是一个页面容器,每一个页面容器可以包含多个页面Ability而每一个Ability对应一个AbilitySlice;虽然Page是一个页面容器,会包含有多个页面,但是当Page进入前台时只会显示一个界面;而系统默认启动的页面就是程序的主页,通过setMainRoute()设置主路由的方法来来进行设置。

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
}

通过setMainRoute方法可以设置在前台显示的一个页面,但是当一个前台需要显示多个多个页面的时候就需要使用到addActionRoute方法进行添加:

@Override
public void onStart(Intent intent) {
    super.onStart(intent);
    super.setMainRoute(MainAbilitySlice.class.getName());
    //action_java自己定义的action行为
    //JavaUiAbility.class.getName()  包名地址
    addActionRoute("action_java",JavaUiAbility.class.getName());
    addActionRoute("action_second",SecondAbility.class.getName());
}

添加了之后发现没有用,因为我们自己定义的action行为没有进行注册,要注册到config.json配置文件里面对应的Ability下,比如我们是在MainAbility里面操作的,那么MainAbility的skills下的actions就需要变成这个样子:

"actions": [
    "action.system.home",
     "action_java",
     "action_second"
]

Intent

Intent是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。Intent的构成元素包括Operation与Parameters。

通过intent的简介可以看到intent主要实现两个作用,1指定要跳转的目标,2携带参数跳转到目标。

Operation

通过Intent的Operation构建对象,实现跳转目标,指定设备标识,应用包名,Ability名称等参数后可以进行Ability之间的跳转;先来看一下Operation的基本属性:

  • Action 表示动作,通常使用系统预置Action,应用也可以自定义Action。例如IntentConstants.ACTION_HOME表示返回桌面动作。同事config.json里面mainAbility的action配置也是采用的系统预置action。
  • Entity 表示类别,通常使用系统预置Entity,应用也可以自定义Entity。例如Intent.ENTITY_HOME表示在桌面显示图标。
  • Uri 表示Uri描述。如果在Intent中指定了Uri,则Intent将匹配指定的Uri信息。如果要访问数据等操作就需要将数据库的配置放在Uri里面。
  • Flags 表示处理intent的方式
  • BundleName 表示包描述。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。
  • AbilityName 表示待启动的Ability名称。如果在Intent中同时指定了BundleName和AbilityName,则Intent可以直接匹配到指定的Ability。
  • DeviceId 表示运行指定Ability的设备ID。

通过参数的基本信息我们可以知道,如果要从AAbility跳转到BAbility就需要设置BundleName和AbilityName,这里的Intent根据指定元素的不同也分为两种跳转类型:

  • 如果同时指定了BundleName与AbilityName,则根据Ability的全称(例如“com.demoapp.FooAbility”)来直接启动应用。这种也行也是用的比较多的。
  • 如果未同时指定BundleName和AbilityName,则根据Operation中的其他属性来启动应用。

实例代码:

Intent intent1 = new Intent();
//跳转目标
Operation operation = new Intent.OperationBuilder()
        .withBundleName("com.example.demo1")
        .withAbilityName("com.example.demo1.SecondAbility")
        .build();
intent1.setOperation(operation);
startAbility(intent1);

作为处理请求的对象,会在相应的回调方法中接收请求方传递的Intent对象。以导航到另一个Ability为例,导航的目标Ability可以在其onStart()回调的参数中获得Intent对象。

Parameters

Parameters是一种支持自定义的数据结构,开发者可以通过Parameters传递某些请求所需的额外信息。他没有具体的子属性,而是通过Key value的形式携带参数进行跳转。

同Page内部跳转三种方式

在同一个Page容器下,内部的Ability之间通过Intent进行跳转又可以分为以下三种情况,分别实现不同操作,同时通过present方法进行跳转。

  1. 无参数跳转
btnJavaUI = (Button) findComponentById(ResourceTable.Id_btnJavaUI);
   btnJavaUI.setClickedListener(component -> {
   Intent javaUIIntent = new Intent();
   present(new JavaUiAbilitySlice(),javaUIIntent);
});
  1. 有参数跳转
    通过intent的setParam和getParam方法可以设置Parameters参数进行跳转以及获取。
    setPram设置参数:
btnJavaUI.setClickedListener(component -> {
   Intent javaUIIntent = new Intent();
   javaUIIntent.setParam("key1","参数1");
   javaUIIntent.setParam("key2","参数2");
   present(new JavaUiAbilitySlice(),javaUIIntent);
});

在跳转过去的页面的onStart()方法中的intent的getParam方法获取参数:

if (intent != null){
	//get 方法获取传递过来的数据
    String key1 = intent.getStringParam("key1");
    String key2 = intent.getStringParam("key2");
    //log 日志打印
    HiLog.error(hiLogLabel,key1 + key2);
}

控制台打印结果:
在这里插入图片描述

  • 携带返回值的跳转
    通过上面两个例子可以知道同Page容器下的不同AbilitySlice之间的跳转使用present方法进行跳转,使用Intent的set方法携带参数,而要接收到B页面返回回来的值就不能使用present方法进行跳转,而是要使用presentForResult进行跳转,而这个方法需要传递三个参数。
  • targetSlice 跳转目标
  • intent 携带参数
  • requestCode 请求响应码(int类型)
//targetSlice 跳转目标
//intent 携带参数
//requestCode 请求响应码(int类型)
public final void presentForResult(AbilitySlice targetSlice, Intent intent, int requestCode) {
    throw new RuntimeException("Stub!");
}

携带参数之后同样在B页面的onStart()方法中使用intent的get方法进行接收。

String key1 = intent.getStringParam("key1");
String key2 = intent.getStringParam("key2");

设置返回值,通过setResult()方法进行设置:

topLayout.setClickedListener(component -> {
     Intent intentResult = new Intent();
     intentResult.setParam("result1","返回的值");
     setResult(intentResult);
     //关闭当前页面
     terminate();
});

在主页面接收的时候需要重写父类的onResult()方法,通过requestCode去判断是否符合我们的条件,如果符合则通过resultIntent的get方法去回去返回的值:

 @Override
protected void onResult(int requestCode, Intent resultIntent) {
   super.onResult(requestCode, resultIntent);
   if (requestCode == 200){
       String resultStr = resultIntent.getStringParam("result1");
       HiLog.error(hiLogLabel,resultStr);
   }
}

看一下输出结果:
在这里插入图片描述

不同Page容器里面的AbilitySlice之间的跳转

不同Page容器里面的Ability之间的跳转就不能使用present方法进行跳转了,需要通过operation的withBundleName和withAbilityName设置跳转目标。

Operation设置跳转目标:

Operation operation = new Intent.OperationBuilder()
       .withBundleName("com.example.demo1")
       .withAbilityName("com.example.demo1.SecondAbility")
       .build();

intent设置携带参数:

intent1.setOperation(operation);
intent1.setParam("key1","携带参数1");
intent1.setParam("key2","携带参数2");

启动方式:

//无返回值
startAbility(intent1);
//有返回值
startAbilityForResult(intent1,200);

接收返回值,重写onAbilityResult方法:

@Override
protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
    super.onAbilityResult(requestCode, resultCode, resultData);
    if (resultCode == 200){
        String resultStr = resultData.getStringParam("result1");
        HiLog.error(hiLogLabel,resultStr);
    }
}
不同Page容器Action方法跳转

Action跳转方法多用于从一个Page的主容器,跳转到另一个Page的非主容器页面。

操作步骤:

  1. 在Page容器中添加AbilitySlice页面
addActionRoute("action_java",JavaUiAbility.class.getName());
  1. 讲行为动作添加到对应的Page主页面下的skills中的action里面去,这里我是新创建了一个SecondAbility当中B Page页面,所以我添加在这里面:
{
   "skills": [{
      "actions": [
         "action_java"
      ]
   }],
   "orientation": "unspecified",
   "name": "com.example.demo1.SecondAbility",
   "icon": "$media:icon",
   "description": "$string:secondability_description",
   "label": "$string:entry_SecondAbility",
   "type": "page",
   "launchType": "standard"
}
  1. 在MainAbility Page的主页面,也就是MainAbility里面通过Intent的setAction方法进行跳转,action的值就是刚才添加的skills下面的action的值:
Intent intent1 = new Intent();
intent1.setAction("JavaUIAbilitySlice");
startAbility(intent1);

这就可以从A Page页面跳转到B Page页面的非主页面了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值