Page模板(以下简称“Page”)是FA唯一支持的模板,用于提供与用户交互的能力。一个Page可以由一个或多个AbilitySlice构成,AbilitySlice是指应用的单个页面及其控制逻辑的总和。当一个Page由多个AbilitySlice共同构成时,这些AbilitySlice页面提供的业务能力应具有高度相关性。
Ability一共有onStart、onActive、onInactive、onBackground、onForeground、onStop几个主要方法,从官网给出的生命周期思维导图就可以基本看出来他们之间的关系。
其中onStart()方法必须重写,因为要设置对应的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是对象之间传递信息的载体。例如,当一个Ability需要启动另一个Ability时,或者一个AbilitySlice需要导航到另一个AbilitySlice时,可以通过Intent指定启动的目标同时携带相关数据。Intent的构成元素包括Operation与Parameters。
通过intent的简介可以看到intent主要实现两个作用,1指定要跳转的目标,2携带参数跳转到目标。
通过Intent的Operation构建对象,实现跳转目标,指定设备标识,应用包名,Ability名称等参数后可以进行Ability之间的跳转;先来看一下Operation的基本属性:
通过参数的基本信息我们可以知道,如果要从AAbility跳转到BAbility就需要设置BundleName和AbilityName,这里的Intent根据指定元素的不同也分为两种跳转类型:
实例代码:
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传递某些请求所需的额外信息。他没有具体的子属性,而是通过Key value的形式携带参数进行跳转。
在同一个Page容器下,内部的Ability之间通过Intent进行跳转又可以分为以下三种情况,分别实现不同操作,同时通过present方法进行跳转。
btnJavaUI = (Button) findComponentById(ResourceTable.Id_btnJavaUI);
btnJavaUI.setClickedListener(component -> {
Intent javaUIIntent = new Intent();
present(new JavaUiAbilitySlice(),javaUIIntent);
});
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);
}
//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容器里面的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);
}
}
Action跳转方法多用于从一个Page的主容器,跳转到另一个Page的非主容器页面。
操作步骤:
addActionRoute("action_java",JavaUiAbility.class.getName());
{
"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"
}
Intent intent1 = new Intent();
intent1.setAction("JavaUIAbilitySlice");
startAbility(intent1);
这就可以从A Page页面跳转到B Page页面的非主页面了。