HarmonyOS application framework - UIAbility in action

UIAbility overview

UIAbility is an application component that contains a user interface and is mainly used to interact with users. UIAbility is also a unit of system scheduling, providing a window for the application to draw the interface. Each UIAbility instance corresponds to a task in the recent task list. An application can have one UIAbility or multiple UIAbility, as shown in the figure below. For example, a browser application can combine multiple pages with a UIAbility to allow users to search and browse content; and if a chat application adds a "takeaway function", the content of the "takeaway function" in the chat application can be independently integrated into a UIAbility , when the user opens the "takeout function" of the chat application and views the details of the takeout order, and there is a new chat message, he or she can switch back to the chat window through the recent task list to continue the chat conversation. A UIAbility can correspond to multiple pages. It is recommended to put an independent functional module into a UIAbility and present it in the form of multiple pages. For example, when browsing content in a news application, you can jump to multiple pages. Figure 1 Single UIAbility application and multiple UIAbility applications

Page jump and data transfer within UIAbility

The data transfer of UIAbility includes the jump and data transfer of pages within UIAbility, and the data jump and data transfer between UIAbility. This chapter mainly explains the jump and data transfer of pages within UIAbility. In a scenario where an application contains a UIAbility, the content of the application can be implemented and enriched by creating multiple pages. This will involve the creation of new pages within UIAbility as well as the jump and data transfer of pages within UIAbility. Open DevEco Studio, select an Empty Ability project template, and create a project, for example, named MyApplication.

  • In the src/main/ets/entryability directory, a UIAbility file EntryAbility.ts will initially be generated. The life cycle callback content of UIAbility can be implemented in the EntryAbility.ts file according to business needs.
  • In the src/main/ets/pages directory, an Index page will be generated. This is also the entry page for applications implemented based on UIAbility. The functions of the portal page can be implemented in the Index page according to business needs.
  • In the src/main/ets/pages directory, right-click New->Page to create a Second page, which is used to jump between pages and transfer data.

In order to implement page jumps and data transfer, a new page needs to be created. Based on the original Index page, create a new page, for example, named Second.ets. Navigation between pages can be achieved through the page routing router module. The page routing module finds the target page according to the page URL to achieve the jump. Through the page routing module, you can use different URLs to access different pages, including jumping to a specified page in UIAbility, replacing the current page with a page in UIAbility, returning to the previous page or a specified page, etc. For specific usage, please refer to ohos.router (page routing).

Page jump and parameter reception Before using page routing, you need to import the router module first, as shown in the following code.

import router from '@ohos.router';

There are several ways to jump to the page. Just choose one method to jump according to your needs.

  • Method 1: API9 and above, the router.pushUrl() method adds a mode parameter, which can be configured as router.RouterMode.Single single-instance mode and router.RouterMode.Standard multi-instance mode. In single instance mode: If the URL of the target page already has the same URL page in the page stack, the page with the same URL closest to the top of the stack will be moved to the top of the stack. The moved page will be a new page, and the original page will still exist in the stack. , the number of elements in the page stack remains unchanged; if the url of the target page does not have the same url page in the page stack and jumps in multi-instance mode, the number of elements in the page stack will be increased by 1. Note: When the number of elements in the page stack is large or exceeds 32, you can clear all historical pages in the page stack by calling the router.clear() method, and only retain the current page as the top page of the stack.
router.pushUrl({
 url: 'pages/Second',
  params: {
    src: 'Index页面传来的数据',
  }
}, router.RouterMode.Single)
  • Method 2: API9 and above, the router.replaceUrl() method adds a mode parameter, which can be configured as router.RouterMode.Single single-instance mode and router.RouterMode.Standard multi-instance mode. In single instance mode: If the url of the target page already has the same url page in the page stack, the page with the same url closest to the top of the stack will be moved to the top of the stack, replace the current page, and destroy the replaced current page. If the page is a new page, the number of elements in the page stack will be reduced by 1; if the URL of the target page does not exist in the page stack with the same URL, it will jump in multi-instance mode, and the number of elements in the page stack will remain unchanged.
router.replaceUrl({
 url: 'pages/Second',
  params: {
    src: 'Index页面传来的数据',
  }
}, router.RouterMode.Single)

The page jump has been implemented. Next, how to receive custom parameters in the Second page? Get the custom parameters passed by the Index page by calling the router.getParams() method.

import router from '@ohos.router';
 
@Entry
@Component
struct Second {
 @State src: string = (router.getParams() as Record<string, string>)['src'];
 // 页面刷新展示
  ...
}

The effect is shown in the figure below. In the Index page, after clicking "Next", you can jump from the Index page to the Second page, and receive parameters and refresh the page in the Second page. Figure 2 Index page jumps to Second page

Page return and parameter reception

We often encounter a scenario where after completing some functional operations on the Second page, we hope to return to the Index page. So how do we achieve this? In the Second page, you can return to the previous page by calling the router.back() method, or add optional options parameters (add url parameters) when calling the router.back() method to return to the specified page. illustrate

  • The target page returned by calling router.back() needs to exist in the page stack to jump normally.
  • For example, call the router.pushUrl() method to jump to the Second page. On the Second page, you can call the router.back() method to return to the previous page.
  • For example, calling the router.clear() method clears all historical pages in the page stack and only retains the current page. At this time, you cannot return to the previous page by calling the router.back() method.
  • Return to the previous page.
router.back();
  • Return to the specified page.
router.back({ url: 'pages/Index' });

The effect is shown in the figure below. In the Second page, click "Back" to return to the Index page from the Second page. Figure 3 Second page returns to Index page

A query dialog box can be added to the page return according to business needs. That is, before calling the router.back() method, you can first call the router.enableBackPageAlert() method to enable the page return inquiry dialog box function. illustrate

  • The router.enableBackPageAlert() method enables the page return query dialog function, which is only effective for the current page. For example, when the router.pushUrl() or router.replaceUrl() method is called, the pages after the jump are all new pages, so before the page returns, the router.enableBackPageAlert() method needs to be called first, and then the page returns to the query dialog box function. will take effect.
  • If you need to turn off the page return query dialog box function, you can turn it off by calling the router.disableAlertBeforeBackPage() method.
router.enableBackPageAlert({
 message: 'Message Info'
});
 
router.back();

In the Second page, when calling the router.back() method to return to the previous page or return to the specified page, continue to add custom parameters as needed, for example, add a custom parameter src when returning.

router.back({
 url: 'pages/Index',
  params: {
    src: 'Second页面传来的数据',
  }
})

Return to the Index page from the Second page. Get the custom parameters passed from the Second page by calling the router.getParams() method on the Index page. illustrate

Calling the router.back() method will not create a new page, but will return the original page. The variables declared by @State in the original page will not be declared repeatedly, and the aboutToAppear() life cycle callback of the page will not be triggered, so it cannot Receive and parse the custom parameters passed by router.back() directly in the variable declaration and the aboutToAppear() life cycle callback of the page. It can be placed where the business needs it for parameter parsing. The sample code parses parameters in the onPageShow() life cycle callback in the Index page.

import router from '@ohos.router';
@Entry
@Component
struct Index {
 @State src: string = '';
 onPageShow() {
 this.src = (router.getParams() as Record<string, string>)['src'];
  }
 // 页面刷新展示
  ...
}

The effect diagram is shown below. In the Second page, after clicking "Back", you can return to the Index page from the Second page, receive parameters in the Index page, and refresh the page for display. Figure 4 The Second page returns to the Index page with parameters

UIAbility life cycle

As users browse, switch, and return to the corresponding application, UIAbility instances in the application will transition between different states in its life cycle. The UIAbility class provides many callbacks, through which you can know that a certain state of the current UIAbility has changed: for example, the creation and destruction of UIAbility, or the state switching of UIAbility between foreground and background. For example, from clicking the gallery application icon on the desktop to launching the gallery application, the status of the application has changed from creation to foreground display. As shown below. Figure 5 Click the gallery application icon from the desktop to start the application

Return to the desktop, switch back to the gallery application from the recent task list, and the application's status has changed from background to foreground display. As shown below. Figure 6 Switch back to the Gallery application from the recent tasks list

During the use of UIAbility, there will be multiple life cycle states. Mastering the life cycle of UIAbility is very important for application development. In order to achieve multi-device tailoring and multi-window scalability, the system decouples component management and window management. The life cycle of UIAbility includes four states: Create, Foreground, Background, and Destroy. WindowStageCreate and WindowStageDestroy are two lifecycle callbacks used by the window manager (WindowStage) to manage UI interface functions in UIAbility, thereby achieving weak coupling between UIAbility and the window. . As shown below. Figure 7 UIAbility life cycle status

  • Create state is triggered when a UIAbility instance is created, and the system will call the onCreate callback. Related initialization operations can be performed in the onCreate callback.
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
 
export default class EntryAbility extends UIAbility {
 onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) {
 // 应用初始化
        ...
    }
    ...
}

For example, when a user opens a battery management application, during the application loading process and before the UI page is visible, the current system power status can be read in the onCreate callback for subsequent UI page display.

  • After the UIAbility instance is created, the system will create a WindowStage before entering Foreground. Each UIAbility instance holds a WindowStage instance. WindowStage is a local window manager, used to manage window-related content, such as focus/defocus, visible/invisible related to the interface. You can set the UI page loading and WindowStage event subscription in the onWindowStageCreate callback. In onWindowStageCreate(windowStage), set the page to be loaded by the application through the loadContent interface. For details on the use of the Window interface, see Window Development Guide.
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
 
export default class EntryAbility extends UIAbility {
    ...
 
 onWindowStageCreate(windowStage: window.WindowStage) {
 // 设置UI页面加载
 // 设置WindowStage的事件订阅(获焦/失焦、可见/不可见)
        ...
 
        windowStage.loadContent('pages/Index', (err, data) => {
            ...
        });
    }
    ...
}

For example, when the user opens a game application and is playing a game, there is a message notification. When the message is opened, the message will pop up in the form of a pop-up window above the game application. At this time, the game application switches from the focus to the out-of-focus state, and the message The application switches to the focused state. For messaging applications, in the onWindowStageCreate callback, the focus event callback will be triggered, and operations such as setting the background color and highlighting of the messaging application can be performed.

  • Foreground and Background states are triggered when UIAbility switches to the foreground or to the background respectively. Correspond to onForeground callback and onBackground callback respectively. onForeground callback is triggered before UIAbility's UI page is visible, that is, when UIAbility switches to the foreground. You can apply for the resources needed by the system in the onForeground callback, or reapply for the resources released in onBackground. onBackground callback is triggered after UIAbility's UI page is completely invisible, that is, when UIAbility switches to the background. You can release useless resources when the UI page is not visible in the onBackground callback, or perform more time-consuming operations in this callback, such as state saving, etc.
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
 
export default class EntryAbility extends UIAbility {
    ...
 
 onForeground() {
 // 申请系统需要的资源,或者重新申请在onBackground中释放的资源
        ...
    }
 
 onBackground() {
 // 释放UI页面不可见时无用的资源,或者在此回调中执行较为耗时的操作
 // 例如状态保存等
        ...
    }
}

For example, when a user opens a map application to view the current geographical location, it is assumed that the map application has obtained the user's positioning permission authorization. Before the UI page is displayed, the positioning function can be turned on in the onForeground callback to obtain the current location information. When the map application switches to the background state, the positioning function can be stopped in the onBackground callback to save system resource consumption.

  • Earlier we learned about the related functions of the onWindowStageCreate callback when creating a UIAbility instance. Corresponds to onWindowStageCreate callback. Before the UIAbility instance is destroyed, the onWindowStageDestroy callback will be entered first, and we can release UI page resources in this callback.
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
 
export default class EntryAbility extends UIAbility {
    ...
 
 onWindowStageDestroy() {
 // 释放UI页面资源
        ...
    }
}

For example, WindowStage subscription events such as focus gain/loss of focus set in onWindowStageCreate.

  • Destroy state, triggered when UIAbility is destroyed. Operations such as releasing system resources and saving data can be performed in the onDestroy callback.
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
 
export default class EntryAbility extends UIAbility {
    ...
 
 onDestroy() {
 // 系统资源的释放、数据的保存等
        ...
    }
}

For example, if the user uses the application's program exit function, the terminalSelf() method of UIAbilityContext will be called, thereby completing the destruction of UIAbility. Or when the user uses the recent task list to close the UIAbility instance, the destruction of the UIAbility will also be completed.

UIAbility startup mode

For applications such as browsers or news, after the user opens the application and browses to access relevant content, he returns to the desktop and opens the application again, and the interface currently accessed by the user is still displayed. For the split-screen operation of applications, users want to use two different applications (such as the Notes application and the Gallery application) to split the screen, and they also hope to use the same application (such as the Notes application itself) to split the screen. For the document application, the user opens a document content from the document application, returns to the document application, and continues to open the same document. It is hoped that the same document content will be opened. Based on the above scenarios, UIAbility currently supports three startup modes: singleton (single instance mode), multiton (multiple instance mode) and specified (specified instance mode). A detailed description of the startup mode is as follows:

  • singleton (single instance mode) When the user opens a browser or news application and browses and accesses related content, then returns to the desktop and opens the application again, the interface currently accessed by the user is still displayed. In this case, UIAbility can be configured as singleton (single instance mode). Each time the startAbility() method is called, if a UIAbility instance of this type already exists in the application process, the UIAbility instance in the system will be reused, and there will be only one UIAbility instance in the system. That is, there is only one UIAbility instance of this type in the recent task list.

  • Multiton (multi-instance mode) When using the split-screen function, users want to split the screen between two different applications (such as the Notes application and the Gallery application), or they also hope to use the same application (such as the Notes application itself) to split the screen. . In this case, UIAbility can be configured as multiton (multi-instance mode). Each time the startAbility() method is called, a UIAbility instance of this type is created in the application process. That is, you can see multiple UIAbility instances of this type in the recent task list.

The external link image transfer failed. The source site may have an anti-leeching mechanism. It is recommended to save the image and upload it directly.

  • specified (specified instance mode) The user opens the document application, opens a document content from the document application, returns to the document application, continues to open the same document, hoping to open the same document content; and creates a new document in the document application , every time you create a new document, you hope to open a new blank document. In this case, UIAbility can be configured as specified (specified instance mode). Before a UIAbility instance is newly created, developers are allowed to create a string Key for the instance. After the newly created UIAbility instance is bound to the Key, each subsequent call to the startAbility method will ask the application which UIAbility instance corresponding to the Key to use to respond to startAbility. ask. If the Key of the UIAbility instance matches, the UIAbility instance bound to it is directly pulled up, otherwise a new UIAbility instance is created. It is up to UIAbility internal business to decide whether to create multiple instances at runtime.

singleton startup mode

Singleton startup mode is also the default startup mode. In singleton startup mode, every time startAbility() is called to start UIAbility, if a UIAbility instance of this type already exists in the application process, the UIAbility instance in the system will be reused, and there will be only one UIAbility instance in the system. To develop and use the singleton launch mode, configure the "launchType" field in the module.json5 file to "singleton".

{
 "module": {
     ...
 "abilities": [
       {
 "launchType": "singleton",
         ...
       }
     ]
  }
}

multiton startup mode

In multiton startup mode, each time the startAbility() method is called, a UIAbility instance of this type will be created in the application process. To develop and use the multiton launch mode, configure the "launchType" field in the module.json5 file to "multiton".

{
 "module": {
     ...
 "abilities": [
       {
 "launchType": "multiton",
         ...
       }
     ]
  }
}

specified startup mode

Specified startup mode, whether to create a new UIAbility instance according to business needs. Before a UIAbility instance is created, the onAcceptWant callback of AbilityStage will be entered. A Key will be created for each UIAbility instance in the onAcceptWant callback. Each subsequent call to the startAbility() method to create a UIAbility instance of this type will ask which Key corresponds to the UIAbility instance. To respond to the startAbility() request. The steps used in the development of specified startup mode are as follows. The "launchType" field in the module.json5 file is configured as "specified".

{
 "module": {
     ...
 "abilities": [
       {
 "launchType": "specified",
         ...
       }
     ]
  }
}
  1. In the want parameter when calling the startAbility() method, add a custom parameter to distinguish the UIAbility instance, for example, add an "instanceKey" custom parameter.
// 在启动指定实例模式的UIAbility时,给每一个UIAbility实例配置一个独立的Key标识
function getInstance() {
    ...
}
let context:common.UIAbilityContext = ...; // context为调用方UIAbility的UIAbilityContext
let want: Want = {
 deviceId: '', // deviceId为空表示本设备
 bundleName: 'com.example.myapplication',
 abilityName: 'SpecifiedAbility',
 moduleName: 'specified', // moduleName非必选
 parameters: { // 自定义信息
 instanceKey: getInstance(),
    },
}
context.startAbility(want).then(() => {
    ...
}).catch((err: BusinessError) => {
    ...
})
  1. In the onAcceptWant life cycle callback of the AbilityStage corresponding to the UIAbility of the pulled party, parse the incoming want parameter and obtain the "instanceKey" custom parameter. Return a string Key identification of the UIAbility instance according to business needs. If the UIAbility identified by this Key has been launched before, the previous UIAbility will be brought back to the foreground and focused without creating a new instance. Otherwise, a new instance will be created and started.
onAcceptWant(want: want): string {
 // 在被启动方的AbilityStage中,针对启动模式为specified的UIAbility返回一个UIAbility实例对应的一个Key值
 // 当前示例指的是device Module的EntryAbility
 if (want.abilityName === 'MainAbility') {
 return `DeviceModule_MainAbilityInstance_${want.parameters.instanceKey}`;
    }
 return '';
}

For example, in a document application, different Key values ​​can be bound to different document instance contents. Each time you create a new document, you can pass in a different new Key value (for example, you can use the file path as a Key identifier). At this time, a new UIAbility instance will be created when UIAbility is started in AbilityStage; when the new document is saved, , return to the desktop, or open a new saved document, return to the desktop, and open the saved document again. When the UIAbility is launched again in AbilityStage, the previously saved document interface will still be opened. Operation examples are shown in the table below.

Operation number Document content UIAbility instance
1 Open file A Corresponds to UIAbility instance 1
2 Close the process that opened file A, return to the desktop, and open file A again. Corresponds to UIAbility instance 2
3 Open file B Corresponds to UIAbility instance 3
4 Open file A again Corresponds to UIAbility instance 2

WeChat picture_20231201170252.png
The full text mainly explains the use cases of UIAbility, the application framework in HarmonyOS development. For more Harmony development, please follow me or the homepage for details.

Guess you like

Origin blog.csdn.net/m0_70748845/article/details/134880594