[Huawei Developers] ask011:
Introduction

In this article, we can create an application showing below features:

1. Page Ability and Ability Slice

2. Page Ability life cycle and Ability Slice life cycle

3. Switching between Ability slices

4. Switching between abilities.

5. Transfer data between abilities.

Requirements

1. DevEco IDE

2. Wearable watch (Can use simulator also)

Harmony OS Supports various 2 types of abilities

1. Feature Ability

2. Particle Ability

In this article, we will test Feature Ability template called Page template.

UI Design

Ability Slice:

An Ability Slice represents a single screen and its control logic.

Page Template (Page Abilities):

Page template is used by Feature ability to interact with users, one page template can contain one or more Ability Slices. Like shown below.

When a Page ability appears in the foreground, it presents one of its ability slices by default.

config.json

I have declared 2 abilities with type page.

{
"app": {
"bundleName": "com.example.threadingsample",
"vendor": "example",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 3,
"target": 3
}
},
"deviceConfig": {},
"module": {
"package": "com.example.threadingsample",
"name": ".MyApplication",
"deviceType": [
"wearable"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"orientation": "landscape",
"name": "com.example.threadingsample.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "ThreadingSample",
"type": "page",
"launchType": "standard"
},
{
"orientation": "landscape",
"name": "com.example.threadingsample.second.SecondAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "SecondAbility",
"type": "page",
"launchType": "standard"
}
]
}
}

Page Ability life cycle

For more information: https://developer.harmonyos.com/en/...uides/ability-page-lifecycle-0000000000029840

Ability Slice life cycle:

An ability slice's lifecycle is bound to the Page ability that hosts it. You must override the onStart() callback of ability slices and use setUIContent() to set the UI content to display in this callback.

Switching between slices

Add the below code in MainAbilitySlice.java

package com.example.threadingsample.slice;

import com.example.threadingsample.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {
static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
Text text;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
HiLog.info(LABEL_LOG, "MainAbilitySlice->"+Thread.currentThread().getName());

text = (Text) findComponentById(ResourceTable.Id_text);

Button launchNewSlice = (Button) findComponentById(ResourceTable.Id_button_launch_new_slice);
launchNewSlice.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
present(new ChildAbilitySlice(), new Intent());
}
});

Button launchNewAbility = (Button) findComponentById(ResourceTable.Id_button_launch_new_ability);
launchNewAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.info(LABEL_LOG, "MainAbilitySlice launch new ability@@->"+Thread.currentThread().getName());

Intent intent = new Intent();

// Use the OperationBuilder class of Intent to construct an Operation object and set the deviceId (left empty if a local ability is required), bundleName, and abilityName attributes for the object.
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.threadingsample")
.withAbilityName("com.example.threadingsample.second.SecondAbility")
.build();

intent.setParam("TEST_KEY", "apple");

// Set the created Operation object to the Intent as its operation attribute.
intent.setOperation(operation);
startAbility(intent);
}
});
}

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

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

Page Ability life cycle

For more information: https://developer.harmonyos.com/en/...uides/ability-page-lifecycle-0000000000029840

Ability Slice life cycle:

An ability slice's lifecycle is bound to the Page ability that hosts it. You must override the onStart() callback of ability slices and use setUIContent() to set the UI content to display in this callback.

Switching between slices

Add the below code in MainAbilitySlice.java

package com.example.threadingsample.slice;

import com.example.threadingsample.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class MainAbilitySlice extends AbilitySlice {
static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
Text text;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_main);
HiLog.info(LABEL_LOG, "MainAbilitySlice->"+Thread.currentThread().getName());

text = (Text) findComponentById(ResourceTable.Id_text);

Button launchNewSlice = (Button) findComponentById(ResourceTable.Id_button_launch_new_slice);
launchNewSlice.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
present(new ChildAbilitySlice(), new Intent());
}
});

Button launchNewAbility = (Button) findComponentById(ResourceTable.Id_button_launch_new_ability);
launchNewAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.info(LABEL_LOG, "MainAbilitySlice launch new ability@@->"+Thread.currentThread().getName());

Intent intent = new Intent();

// Use the OperationBuilder class of Intent to construct an Operation object and set the deviceId (left empty if a local ability is required), bundleName, and abilityName attributes for the object.
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.threadingsample")
.withAbilityName("com.example.threadingsample.second.SecondAbility")
.build();

intent.setParam("TEST_KEY", "apple");

// Set the created Operation object to the Intent as its operation attribute.
intent.setOperation(operation);
startAbility(intent);
}
});
}

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

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

Add below code in ability_main.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:background_element="#8c7373"
ohos:padding="32">

<Text
ohos:multiple_lines="true"
ohos:id="$+id:text"
ohos:height="match_content"
ohos:width="200"
ohos:layout_alignment="horizontal_center"
ohos:text="Text"
ohos:text_size="10fp"/>

<Button
ohos:id="$+id:button_launch_new_slice"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:padding="5"
ohos:text="Launch new Slice"
ohos:text_size="30"
ohos:top_margin="5"/>

<Button
ohos:id="$+id:button_launch_new_ability"
ohos:height="match_content"
ohos:width="match_content"
ohos:background_element="$graphic:background_button"
ohos:layout_alignment="horizontal_center"
ohos:padding="5"
ohos:text="Launch new Ability"
ohos:text_size="30"
ohos:top_margin="5"/>

</DirectionalLayout>

Add the below code in ChildAbilitySlice.java

package com.example.threadingsample.slice;

import com.example.threadingsample.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.Text;
import ohos.app.dispatcher.TaskDispatcher;
import ohos.app.dispatcher.task.TaskPriority;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class ChildAbilitySlice extends AbilitySlice {
static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");
Text text;
@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_child_slice_two);
HiLog.info(LABEL_LOG, "ChildAbilitySlice->"+Thread.currentThread().getName());
}

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

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

Add the below code in child_slice_two.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:background_element="#8c7373"
ohos:padding="32">

<Text
ohos:multiple_lines="true"
ohos:id="$+id:text"
ohos:height="match_content"
ohos:width="200"
ohos:layout_alignment="horizontal_center"
ohos:text="Child Slice"
ohos:text_size="10fp"/>

</DirectionalLayout>

Switch from MainAbilitySlice to ChildAbilitySlice using present method.

Button launchNewSlice = (Button) findComponentById(ResourceTable.Id_button_launch_new_slice);
launchNewSlice.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
present(new ChildAbilitySlice(), new Intent());
}
});

Switching from MainAbility to SecondAbility.

Button launchNewAbility = (Button) findComponentById(ResourceTable.Id_button_launch_new_ability);
launchNewAbility.setClickedListener(new Component.ClickedListener() {
@Override
public void onClick(Component component) {
HiLog.info(LABEL_LOG, "MainAbilitySlice launch new ability@@->"+Thread.currentThread().getName());

Intent intent = new Intent();

// Use the OperationBuilder class of Intent to construct an Operation object and set the deviceId (left empty if a local ability is required), bundleName, and abilityName attributes for the object.
Operation operation = new Intent.OperationBuilder()
.withDeviceId("")
.withBundleName("com.example.threadingsample")
.withAbilityName("com.example.threadingsample.second.SecondAbility")
.build();

intent.setParam("TEST_KEY", "apple");

// Set the created Operation object to the Intent as its operation attribute.
intent.setOperation(operation);
startAbility(intent);
}
});

Add the below code to SecondAbility.java

package com.example.threadingsample.second;

import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Intent;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class SecondAbility extends Ability {
private static final int MY_PERMISSIONS_REQUEST_LOCATION = 1001;
static final HiLogLabel LABEL = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");

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

Add the below code in SecondAbilitySlice.java

package com.example.threadingsample.second;

import com.example.threadingsample.ResourceTable;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Text;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

public class SecondAbilitySlice extends AbilitySlice {
static final HiLogLabel LABEL_LOG = new HiLogLabel(HiLog.LOG_APP, 0x00201, "MY_TAG");

@Override
public void onStart(Intent intent) {
super.onStart(intent);
super.setUIContent(ResourceTable.Layout_ability_two);
HiLog.info(LABEL_LOG, "inside SecondAbilitySlice!!");
if(getAbility() != null) {
if (getAbility().getIntent() != null) {
if (getAbility().getIntent().hasParameter("TEST_KEY")) {
String valueFromFirstAbility = getAbility().getIntent().getStringParam("TEST_KEY");
HiLog.info(LABEL_LOG, "inside SecondAbilitySlice@@-->"+valueFromFirstAbility);
Text text = (Text) findComponentById(ResourceTable.Id_text);
text.setText(valueFromFirstAbility);
} else {
HiLog.info(LABEL_LOG, "TEST_KEY parameter is not present");
}
} else {
HiLog.info(LABEL_LOG, "intent is null");
}
}else{
HiLog.info(LABEL_LOG, "ability is null");
}

}

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

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

Add the below code in ability_two.xml

<?xml version="1.0" encoding="utf-8"?>
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:background_element="#8c7373"
ohos:padding="32">

<Text
ohos:multiple_lines="true"
ohos:id="$+id:text"
ohos:height="match_content"
ohos:width="200"
ohos:layout_alignment="horizontal_center"
ohos:text="Ability2"
ohos:text_size="10fp"/>

</DirectionalLayout>

Transfer data from one ability to another

Intent intent = new Intent();
intent.setParam("TEST_KEY", "apple");

Retrieve data on other ability

if(getAbility() != null) {
if (getAbility().getIntent() != null) {
if (getAbility().getIntent().hasParameter("TEST_KEY")) {
String valueFromFirstAbility = getAbility().getIntent().getStringParam("TEST_KEY");
HiLog.info(LABEL_LOG, "inside SecondAbilitySlice@@-->"+valueFromFirstAbility);
Text text = (Text) findComponentById(ResourceTable.Id_text);
text.setText(valueFromFirstAbility);
} else {
HiLog.info(LABEL_LOG, "TEST_KEY parameter is not present");
}
} else {
HiLog.info(LABEL_LOG, "intent is null");
}
}else{
HiLog.info(LABEL_LOG, "ability is null");
}

Tips and Tricks

All Abilities must be registered into config.json

Conclusion

In this article, we have UI components, there life cycle and navigation between them, transfer data between two pages.

Reference

Harmony Official document

DevEco Studio User guide

JS API Reference

Read In Forum