[Daily HarmonyOS Next Knowledge] Asynchronous Interface Judgment, Event Bubbling, Split-Screen Disable, Long Screenshot, Screenshot Prevention
1. How do HarmonyOS developers independently determine if an interface is asynchronous?
How to independently determine an asynchronous interface?
Asynchronous concurrency is implemented via Promise and async/await. Interfaces using these implementations can be considered asynchronous. For details, refer to the documentation: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/async-concurrency-overview-V5?catalogVersion=V5
Promise and async/await provide asynchronous concurrency capabilities and follow standard JS asynchronous syntax. Asynchronous code is suspended and resumed later, with only one code segment executing at a time. This suits single I/O tasks like network requests or file read/write operations, eliminating the need for additional threads.
Asynchronous syntax is a programming language feature allowing programs to execute other operations without waiting for certain tasks to complete.
Promise: An object for handling asynchronous operations, converting them into a synchronous-like style for easier coding and maintenance. It uses a state mechanism to manage asynchronous phases and provides methods to register callbacks for successful or failed outcomes.
- Promise states: pending (in progress), fulfilled (completed), rejected (failed).
-
Basic usage: Instantiate via a constructor with an executor function taking
resolve
(success callback) andreject
(failure callback). Example:
const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
setTimeout(() => {
const randomNumber: number = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject(new Error('Random number is too small'));
}
}, 1000);
})
async/await: A Promise syntax sugar for handling asynchronous operations, simplifying and enhancing readability. Declare a function as asynchronous with async
and use await
to wait for Promise resolution.
- An
async
function returns a Promise, representing an asynchronous operation.await
waits for Promise resolution and returns its value. If an exception is thrown, the returned Promise is rejected. - Example simulating a synchronous-style asynchronous operation:
async function myAsyncFunction(): Promise<string> {
const result: string = await new Promise((resolve: Function) => {
setTimeout(() => {
resolve('Hello, world!');
}, 3000);
});
console.info(result); // Output: Hello, world!
return result;
}
@Entry
@Component
struct Index {
@State message: string = 'Hello World';
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
.onClick(async () => {
let res = await myAsyncFunction();
console.info("res is: " + res);
})
}
.width('100%')
}
.height('100%')
}
}
2. How are event bubbling and event delegation implemented in HarmonyOS NEXT?
For event bubbling, refer to the documentation: https://gitee.com/sunfei2021/ace-test-source/blob/master/specs/event_spec.md#%E8%A7%A6%E6%91%B8%E4%BA%8B%E4%BB%B6%E6%B5%81%E7%A8%8B
Touch events include three complete phases:
- Event touch test: Triggered on touch down (TouchDown). Starting from the root node, a hit test finds the event distribution path via touch coordinates.
- Event distribution: Distributes events sequentially along the path generated by the touch test (gesture recognition occurs here).
- Event response bubbling: When reaching a leaf node, if the node can respond, the event triggers and bubbles up to parent nodes for response.
graph TD
S[Start from root node] --> A
A[Acquire node] --> B[Get current touch point coordinates]
B --> C[Process affine transformation of current node]
C --> ENABLE{Is event disabled?}
ENABLE --NO--> I{HitTestMode is None?}
ENABLE -- YES --> G{Is there a next sibling?}
I --YES--> H[Convert touch point to child node coordinate system]
I --NO--> E{Is touch point within current node's hit area?}
E -- YES --> F[Add current node to event distribution list]
E -- NO --> G
F --> H
H --> D{HitTestMode is Block?}
D --YES--> L
D --NO--> K{Are there child nodes?}
G --YES--> A
G --NO--> L{Is there a parent node?}
K --YES--> A
K --NO--> L
L --YES--> M{Parent node HitTestMode is None or Transparent?}
L --NO--> J[End]
M --YES--> G
M --NO--> L
Touch test process specifications:
- Touch testing is required only for single-point touch down (TouchDown).
- The starting node is the window root, with coordinates relative to the window.
- Subsequent tests use coordinates relative to the parent node.
- Check if the touch point falls within the node's hit area (set by
responseRegion
, defaulting to the display area). - The default hit area includes the border.
- Consider the node's graphic transformations relative to the parent.
- Account for
hitTestBehavior
(general attribute) andenabled
(blocks self-testing, not siblings). - Siblings are traversed in descending order of
zIndex
(or reverse order if nozIndex
). - Nodes meeting test conditions form a distribution tree for subsequent event distribution.
3. How to disable app split-screen or floating window display in HarmonyOS?
Disable split-screen or floating window display by setting supportWindowMode
: Identifies the window modes supported by the UIAbility component. Values include:
-
fullscreen
: Full-screen mode. -
split
: Split-screen mode. -
floating
: Floating window mode.
To disable split-screen/floating window, set supportWindowMode
to ["fullscreen"]
.
4. When taking a long screenshot in HarmonyOS, why does the underlying page get captured if multiple pages reuse the same ID?
When using the screenshot component, ensure unique component IDs. Reusing IDs will reference the first component.
5. How to prevent screenshots in HarmonyOS?
To enable screenshot prevention on a specific page, follow these steps and refer to the demo:
- Declare permission in module.json5:
"requestPermissions": [
{
"name": "ohos.permission.PRIVACY_WINDOW"
}
]
- Sample code:
// windowUtils.ets
import window from '@ohos.window';
import common from '@ohos.app.ability.common';
export class windowUtils {
static setWindowPrivacyModeInPage(context: common.UIAbilityContext, isFlag: boolean) {
window.getLastWindow(context).then((lastWindow)=>{
lastWindow.setWindowPrivacyMode(isFlag);
})
}
}
// Page
import common from '@ohos.app.ability.common';
import { windowUtils } from '../common/windowUtils';
@Entry
@Component
struct Index3 {
@State message: string = 'Hello World';
onPageShow(): void {
windowUtils.setWindowPrivacyModeInPage(getContext(this) as common.UIAbilityContext, true);
}
onPageHide() {
windowUtils.setWindowPrivacyModeInPage(getContext(this) as common.UIAbilityContext, false);
}
build() {
Row() {
Column() {
Text(this.message)
.fontSize(50)
.fontWeight(FontWeight.Bold)
}
.width('100%')
}
.height('100%')
}
}
Top comments (0)