DEV Community

HarmonyOS
HarmonyOS

Posted on

UIAbility Intra-Device Interaction in HarmonyOS Next

Read the original article:UIAbility Intra-Device Interaction in HarmonyOS Next

Introduction

In HarmonyOS Next, UIAbility components enable seamless interaction between different parts of an application or even across different applications on the same device. Understanding how UIAbility components communicate is crucial for building modular, efficient, and user-friendly apps.

This guide explores intra-device interaction — how UIAbility instances can start, stop, and exchange data with each other within the same device.

1. Starting a UIAbility Explicitly

How It Works

  • Use startAbility() with an explicit Want (a structured intent-like object) to launch another UIAbility.
  • The target UIAbility must be declared in the module.json5 file.

Example: Opening a Settings Page

import { common, Want } from '@kit.AbilityKit';
let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext;  
let want: Want = {  
  deviceId: '', // Local device  
  bundleName: 'com.example.settings',  
  abilityName: 'SettingsAbility',  
};  
context.startAbility(want).then(() => {  
  console.log('SettingsAbility started successfully.');  
}).catch((err) => {  
  console.error(`Failed to start SettingsAbility. Error: ${err.message}`);  
});
Enter fullscreen mode Exit fullscreen mode

Key Points

✅ Explicit Intent: Must specify bundleName and abilityName.
✅ Error Handling: Check for failures (e.g., if the target UIAbility doesn’t exist).

2. Starting a UIAbility Implicitly

How It Works

  • Instead of specifying the exact UIAbility, you define an action (e.g., "view.document").
  • The system matches the best UIAbility to handle the request.

Example: Opening a PDF File

let want: Want = {  
  action: 'ohos.want.action.view',  
  entities: ['entity.system.file'],  
  uri: 'file://docs/sample.pdf',  
};
context.startAbility(want).then(() => {  
  console.log('PDF viewer opened successfully.');  
}).catch((err) => {  
  console.error(`Failed to open PDF. Error: ${err.message}`);  
});
Enter fullscreen mode Exit fullscreen mode

Key Points

✅ Flexible Matching: Multiple apps can handle the same action (user may choose).
✅ Common Use Cases: File sharing, deep linking, and default app behaviors.

3. Passing Data Between UIAbilities

Using `parameters` in Want

You can send extra data when starting a UIAbility:

let want: Want = {  
  bundleName: 'com.example.app',  
  abilityName: 'DetailAbility',  
  parameters: {  
    itemId: '123',  
    userToken: 'xyz789'  
  }  
};
context.startAbility(want);
Enter fullscreen mode Exit fullscreen mode

Retrieving Data in the Target UIAbility

import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
export default class DetailAbility extends UIAbility {  
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {  
    const itemId = want.parameters?.itemId; // '123'  
    const userToken = want.parameters?.userToken; // 'xyz789'  
  }  
}
Enter fullscreen mode Exit fullscreen mode

Key Points

✅ Simple Data Transfer: Works for primitives (strings, numbers).
⚠️Avoid Large Data: Use DataShareExtensionAbility for big payloads.

4. Returning Results from a UIAbility

How It Works

  • The caller UIAbility can wait for a result from the target UIAbility.
  • Useful for confirmation dialogs, pickers, or settings adjustments.

Example: Requesting User Confirmation

Caller UIAbility (Request)

let want: Want = {  
  bundleName: 'com.example.dialog',  
  abilityName: 'ConfirmationAbility',  
};
context.startAbilityForResult(want).then((result) => {  
  if (result.resultCode === 0) {  
    console.log('User confirmed:', result.want?.parameters?.isConfirmed);  
  }  
}).catch((err) => {  
  console.error('Failed to get result:', err);  
});
Enter fullscreen mode Exit fullscreen mode

Target UIAbility (Response)

import { AbilityConstant, UIAbility } from '@kit.AbilityKit';
export default class ConfirmationAbility extends UIAbility {  
  onBackPress() {  
    this.context.terminateSelfWithResult({  
      resultCode: 0,  
      want: {  
        parameters: {  
          isConfirmed: true  
        }  
      }  
    });  
    return true;  
  }  
}
Enter fullscreen mode Exit fullscreen mode

Key Points

✅ Asynchronous Handling: Caller waits for a response.
✅ Result Codes: Use resultCode (e.g., 0 for success, -1 for failure).

5. Best Practices for UIAbility Interaction

  1. Minimize Dependencies — Avoid tight coupling between UIAbilities.
  2. Use Implicit Intents for Flexibility — Let the system resolve the best handler.
  3. Optimize Data Transfer — For large data, use DataShare or IPC.
  4. Handle Errors Gracefully — Check for missing abilities or permissions.

Conclusion

UIAbility intra-device interaction in HarmonyOS Next provides powerful ways to:
🔹 Start abilities explicitly or implicitly
🔹 Pass data between components
🔹 Receive results from launched abilities

By mastering these techniques, developers can build modular, responsive, and user-friendly apps.

Further Reading:

https://developer.huawei.com/consumer/en/doc/harmonyos-guides/uiability-intra-device-interaction

Written by Jeorge Kiryienko

Top comments (0)