diff --git a/en/application-dev/ability-deprecated/Readme-EN.md b/en/application-dev/ability-deprecated/Readme-EN.md deleted file mode 100644 index 5c803a47558bbd52765090debe162dbecd996ae6..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/Readme-EN.md +++ /dev/null @@ -1,25 +0,0 @@ -# Ability Development - -> **NOTE**
-> This folder is deprecated. Read [Application Models](../application-models/Readme-EN.md) instead. - -- [Ability Framework Overview](ability-brief.md) -- [Context Usage](context-userguide.md) -- FA Model - - [FA Model Overview](fa-brief.md) - - [Page Ability Development](fa-pageability.md) - - [Service Ability Development](fa-serviceability.md) - - [Data Ability Development](fa-dataability.md) - - [FA Widget Development](fa-formability.md) -- Stage Model - - [Stage Model Overview](stage-brief.md) - - [Ability Development](stage-ability.md) - - [Service Extension Ability Development](stage-serviceextension.md) - - [Ability Continuation Development](stage-ability-continuation.md) - - [Ability Call Development](stage-call.md) - - [Stage Widget Development](stage-formextension.md) -- Other - - [WantAgent Development](wantagent.md) - - [Ability Assistant Usage](ability-assistant-guidelines.md) - - [ContinuationManager Development](continuationmanager.md) - - [Test Framework Usage](ability-delegator.md) diff --git a/en/application-dev/ability-deprecated/ability-assistant-guidelines.md b/en/application-dev/ability-deprecated/ability-assistant-guidelines.md deleted file mode 100644 index d2e45f5d5492c23bcce0ec48674427df2cb2b765..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/ability-assistant-guidelines.md +++ /dev/null @@ -1,107 +0,0 @@ -# Ability Assistant Usage - -The ability assistant enables you to start applications, atomic services, and test cases and debug applications. By using this tool, you can send commands in the hdc shell to perform various system operations, such as starting abilities, forcibly stopping processes, and printing ability information. - -## Query-related Commands - -- **help** - - Displays help information for the ability assistant. - - **Return value** - - Returns the help information. - - **Method** - - ``` - aa help - ``` - -## Ability-related Commands - -- **start** - - Starts an ability. - - | Name | Description | - | --------- | -------------------------- | - | -h/--help | Help information. | - | -d | Device ID. This parameter is optional. | - | -a | Ability name. This parameter is mandatory.| - | -b | Bundle name. This parameter is mandatory. | - | -D | Debugging mode. This parameter is optional. | - - **Return value** - - Returns "start ability successfully." if the ability is started; returns "error: failed to start ability." otherwise. - - **Method** - - ``` - aa start [-d ] -a -b [-D] - ``` - -- **stop-service** - - Stops a Service ability. - - | Name | Description | - | --------- | ------------------------ | - | -h/--help | Help information. | - | -d | Device ID. This parameter is optional. | - | -a | Ability name. This parameter is mandatory.| - | -b | Bundle name. This parameter is mandatory. | - - **Return value** - - Returns "stop service ability successfully." if the Service ability is stopped; returns "error: failed to stop service ability." otherwise. - - **Method** - - ``` - aa stop-service [-d ] -a -b - ``` - -- **dump** - - Prints ability-related information. - - | Name | Level-2 Parameter | Description | - | ----------------- | -------------------- | ------------------------------------------------------------ | - | -h/--help | - | Prints help information. | - | -a/--all | - | Prints ability information in all missions. | - | -l/--mission-list | type (All logs are printed if this parameter is left unspecified.)| Prints mission stack information.
The following values are available for **type**:
- NORMAL
- DEFAULT_STANDARD
- DEFAULT_SINGLE
- LAUNCHER | - | -e/--extension | elementName | Prints extended component information. | - | -u/--userId | UserId | Prints stack information of a specified user ID. This parameter must be used together with other parameters.
Example commands: aa **dump -a -u 100** and **aa dump -d -u 100**.| - | -d/--data | - | Prints Data ability information. | - | -i/--ability | AbilityRecord ID | Prints detailed information about a specified ability. | - | -c/--client | - | Prints detailed ability information. This parameter must be used together with other parameters.
Example commands: **aa dump -a -c** and **aa dump -i 21 -c**.| - - **Method** - - ``` - aa dump -a - ``` - ![aa-dump-a](figures/aa-dump-a.PNG) - ``` - aa dump -l - ``` - ![aa-dump-l](figures/aa-dump-l.PNG) - ``` - aa dump -i 12 - ``` - ![aa-dump-i](figures/aa-dump-i.PNG) -- **force-stop** - - Forcibly stops a process based on the bundle name. - - **Return value** - - Returns "force stop process successfully." if the process is forcibly stopped; returns "error: failed to force stop process." otherwise. - - **Method** - - ``` - aa force-stop - ``` diff --git a/en/application-dev/ability-deprecated/ability-brief.md b/en/application-dev/ability-deprecated/ability-brief.md deleted file mode 100644 index 867e2c750a7d98b7964b037dcb809954fb5b40fb..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/ability-brief.md +++ /dev/null @@ -1,34 +0,0 @@ -# Ability Framework Overview - -Ability is the basic abstraction of applications in OpenHarmony. - -Each ability is an application component that provides an independent service and is the minimum unit for the system to schedule an application. An application can contain one or more **Ability** instances. - -The ability framework model has two forms: - -- FA model, which is available for application development using API version 8 and earlier versions. In the FA model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility. -- Stage model, which is introduced since API version 9. In the stage model, there are two classes: UIAbility and ExtensionAbility. ExtensionAbility is further extended to ServiceExtensionAbility, FormExtensionAbility, DataShareExtensionAbility, and more. - -Starting from API version 9, the stage model is recommended. - -The stage model is designed to make it easier to develop complex applications in the distributed environment. The table below lists the design differences between the two models. - -| Item | FA Model | Stage Model | -| -------------- | ------------------------------------------------------------ | -------------------------------------------------------- | -| Application component development mode | Web-like development | Object-oriented development | -| Engine instance | Each **Ability** instance exclusively occupies a VM instance. | Multiple **Ability** instances share a VM instance. | -| Intra-process object sharing| Not supported | Supported | -| Bundle description file | The **config.json** file is used to describe the HAP and component information. Each component must use a fixed file name.| The **module.json5** file is used to describe the HAP and component information. The entry file name can be specified.| -| Component | Four types of components are provided: PageAbility (used for UI page display), ServiceAbility (used to provide services), DataAbility (used for data sharing), and FormAbility (used to provide widgets).| Two types of components are provided: UIAbility (used for UI page display) and ExtensionAbility (scenario-based service extension). | - -In addition, the following differences exist in the development process: - -* Different ability types - - ![favsstage](figures/favsstage.png) - -* Different ability lifecycles - - ![lifecycle](figures/lifecycle.png) - -For details about the two models, see [FA Model Overview](fa-brief.md) and [Stage Model Overview](stage-brief.md). diff --git a/en/application-dev/ability-deprecated/ability-delegator.md b/en/application-dev/ability-deprecated/ability-delegator.md deleted file mode 100644 index 8f0fd5cc701e9508757998ac0164bd6eec1b2940..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/ability-delegator.md +++ /dev/null @@ -1,181 +0,0 @@ -# Test Framework Usage - -## Overview -The delegator test framework provides a self-test environment for OpenHarmony applications. Using this framework, you can start an ability, schedule its lifecycle, listen for its state changes, run a shell command, and print the test result. - -## Constraints - -The APIs provided by the test framework can be used only in the test HAP. They take effect only after the test framework is started. - - -## Starting the Test Framework - -The test framework can be started in either of the following ways: - -- Method 1: Run the `aa test` command. -- Method 2: Use DevEco Studio. - -### Running aa test - -To start the test framework, specify the **TestRunner** and the package name or module name of the HAP where the **TestRunner** is located. - -An example command in the FA model is as follows: - -```javascript -aa test -b BundleName -p com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20 -``` - -An example command in the stage model is as follows: -```javascript -aa test -b BundleName -m com.example.myapplicationfaets -s unittest OpenHarmonyTestRunner -s class ActsAbilityTest -w 20 -``` -| Parameter | Mandatory| Description | -| --------------- | -------- | ------------------------------------------------------------ | -| -b | Yes | Bundle name of the HAP where the **TestRunner** is located. | -| -p | Yes | Package name of the HAP where the **TestRunner** is located. This parameter is used by the FA model. | -| -m | Yes | Module name of the HAP where the **TestRunner** is located. This parameter is used by the stage model. | -| -s unittest | Yes | Name of the **TestRunner** to be used. The TestRunner name must be the same as the file name. | -| -w | No | Timeout interval of a test case, in seconds. If this parameter is not specified or is set to a value less than or equal to **0**, the test framework exits only after **finishTest** is invoked.| -| -s \\ | No | **-s** can be followed by any key-value pair obtained through **AbilityDelegatorArgs.parameters**. For example, in **-s classname myTest**, **-s classname** is the key and **myTest** is the value.| -| -D | No | Debug mode for starting the tested application.| -| -h | No | Help information.| - -### Using DevEco Studio - -For details about how to use DevEco Studio to start the test framework, see [OpenHarmony Test Framework](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-openharmony-test-framework-0000001263160453#section1034420367508). - -## Introduction to TestRunner - -**TestRunner** is the entry class of the test framework test process. When the test process is started, the system calls related APIs in **TestRunner**. You need to inherit this class and override the **onPrepare** and **onRun** APIs. When creating an application template, DevEco Studio initializes the default **TestRunner** and starts the default **TestAbility** in the **onRun** API. You can modify the test code of **TestAbility** or override **onPrepare** and **onRun** in **TestRunner** to implement your own test code. For details, see [TestRunner](../reference/apis/js-apis-application-testRunner.md). - -## Introduction to AbilityDelegatorRegistry - -**AbilityDelegatorRegistry** is the **AbilityDelegator** repository class provided by the test framework. You can use **AbilityDelegatorRegistry** to obtain an **AbilityDelegator** instance and the input and generated parameters **AbilityDelegatorArgs** during the test. You can use **AbilityDelegator** to invoke the function set provided by the test framework for testing and verification. For details, see [AbilityDelegatorRegistry](../reference/apis/js-apis-application-abilityDelegatorRegistry.md). - -## Introduction to AbilityDelegatorArgs - -**AbilityDelegatorArgs** is a test parameter class provided by the test framework. You can use **AbilityDelegatorArgs** to obtain the parameters passed and generated during the test. For details, see [AbilityDelegatorArgs](../reference/apis/js-apis-inner-application-abilityDelegatorArgs.md). - -## Introduction to AbilityMonitor - -**AbilityMonitor** is provided by the test framework for binding to and listening for abilities. You can use **AbilityMonitor** to bind to an **Ability** instance and add **AbilityMonitor** to the listening list. When **AbilityMonitor** is bound to an ability, the creation and lifecycle changes of the ability will trigger the related callback in **AbilityMonitor**. You can test and verify the ability in these callbacks. For details, see [AbilityMonitor](../reference/apis/js-apis-application-abilityMonitor.md). - -**Example** - -```javascript -import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' - -function onAbilityCreateCallback(data) { - console.info("onAbilityCreateCallback"); -} - -var monitor = { - abilityName: "abilityname", - onAbilityCreate: onAbilityCreateCallback -} - -var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.addAbilityMonitor(monitor).then(() => { - console.info("addAbilityMonitor promise"); -}); -``` - -## Introduction to AbilityDelegator - -**AbilityDelegator** is a main function class of the test framework. It provides the functions of starting an ability, obtaining an **Ability** instance, scheduling the ability lifecycle, listening for the ability state, and printing test results. - -**Modules to Import** - -```javascript -import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry' -``` - -```javascript -var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() -``` - -### Starting an Ability and Listening for the Ability State - -Use **AbilityDelegator** and **AbilityMonitor** to start an ability, obtain an **Ability** instance, and listen for the ability state. - -**Example** - -```javascript -var abilityDelegator; -var ability; -var timeout = 100; - -function onAbilityCreateCallback(data) { - console.info("onAbilityCreateCallback"); -} - -var monitor = { - abilityName: "abilityname", - onAbilityCreate: onAbilityCreateCallback -} - -abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.waitAbilityMonitor(monitor, timeout, (err, data) => { - ability = data; - console.info("waitAbilityMonitor callback"); -}); - -var want = { - bundleName: "bundleName", - abilityName: "abilityName" -}; -abilityDelegator.startAbility(want, (err, data) => { - console.info("startAbility callback"); -}); -``` - -### Scheduling the Ability Lifecycle - -**AbilityDelegator** provides APIs to display and schedule the ability lifecycle and supports the foreground and background. It works with **AbilityMonitor** to listen for the ability lifecycle. For details, see [AbilityDelegator](../reference/apis/js-apis-inner-application-abilityDelegator.md). - -### Running a Shell Command - -**AbilityDelegator** provides APIs to run shell commands in the test environment. - -**Example** - -```javascript -var abilityDelegator; -var cmd = "cmd"; -abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.executeShellCommand(cmd, (err, data) => { - console.info("executeShellCommand callback"); -}); -``` - -### Printing Log Information - -**AbilityDelegator** provides APIs for printing log information. You can call any API in the test code to print process logs to the unit test console. - -**Example** - -```javascript -var abilityDelegator; -var msg = "msg"; - -abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.print(msg, (err) => { - console.info("print callback"); -}); -``` - -### Finishing the Test and Printing Log Information - -**AbilityDelegator** provides the APIs for actively finishing the test. You can call any API in test code to finish the test and print logs to the unit test console. - -**Example** - -```javascript -var abilityDelegator; -var msg = "msg"; - -abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator(); -abilityDelegator.finishTest(msg, 0, (err) => { - console.info("finishTest callback"); -}); -``` diff --git a/en/application-dev/ability-deprecated/context-userguide.md b/en/application-dev/ability-deprecated/context-userguide.md deleted file mode 100644 index 12bf09b757df626cb424899a1e7bffb36a96b4bb..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/context-userguide.md +++ /dev/null @@ -1,319 +0,0 @@ -# Context Usage - -## Context Overview - -**Context** provides the capability of obtaining contextual information of an application. - -The OpenHarmony application framework has two models: Feature Ability (FA) model and stage model. Correspondingly, there are two sets of context mechanisms. **application/BaseContext** is a common context base class. It uses the **stageMode** attribute to specify whether the context is used for the stage model. - -- FA model - - Only the methods in **app/Context** can be used for the context in the FA model. Both the application-level context and ability-level context are instances of this type. If an ability-level method is invoked in the application-level context, an error occurs. Therefore, you must pay attention to the actual meaning of the **Context** instance. - -- Stage model - - The stage model has the following types of contexts: **application/Context**, **application/ApplicationContext**, **application/AbilityStageContext**, **application/ExtensionContext**, **application/AbilityContext**, and **application/FormExtensionContext**. For details about these contexts and how to use them, see [Context in the Stage Model](#context-in-the-stage-model). - -![contextIntroduction](figures/contextIntroduction.png) - -## Context in the FA Model - -Only the methods in **app/Context** can be used for the context in the FA model. - -The FA model has only one context definition. All capabilities in the context are provided through methods. The context uses these methods to extend the capabilities of the FA. - -**d.ts statement** - -https://gitee.com/openharmony/interface_sdk-js/blob/master/api/app/context.d.ts - -**Example** - -```javascript -import featureAbility from '@ohos.ability.featureAbility' -export default { - onCreate() { - // Obtain the context and call related APIs. - let context = featureAbility.getContext(); - context.getBundleName((data, bundleName)=>{ - console.info("ability bundleName:" + bundleName) - }); - console.info('Application onCreate') - }, - onDestroy() { - console.info('Application onDestroy') - }, -} -``` - -### Common Context-related Methods in the FA Model -The following context-related methods are available in the FA model: -```javascript -setDisplayOrientation(orientation: bundle.DisplayOrientation, callback: AsyncCallback): void -setDisplayOrientation(orientation: bundle.DisplayOrientation): Promise; -``` -The methods are used to set the display orientation of the current ability. - -**Example** - -```javascript -import featureAbility from '@ohos.ability.featureAbility' -import bundle from '@ohos.bundle'; - -export default { - onCreate() { - // Obtain the context and call related APIs. - let context = featureAbility.getContext(); - context.setDisplayOrientation(bundle.DisplayOrientation.LANDSCAPE).then(() => { - console.log("Set display orientation.") - }) - console.info('Application onCreate') - }, - onDestroy() { - console.info('Application onDestroy') - }, -} -``` - -## Context in the Stage Model - -The following describes the contexts provided by the stage model in detail. - -### application/Context - -**application/Context** is the base class context. It provides basic application information, such as **resourceManager**, **applicationInfo**, **cacheDir**, and **area**. It also provides basic application methods such as **createModuleContext**. - -**d.ts statement** - -https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/Context.d.ts - -### application/ApplicationContext - -**application/ApplicationContext** is an application-level context. In addition to the capabilities provided by the base class context, the application-level context provides **registerAbilityLifecycleCallback** and **unregisterAbilityLifecycleCallback** to monitor the ability lifecycle in a process. - -**How to Obtain** - -Obtain the context by calling **context.getApplicationContext()** in **Ability**. - -**Example** - -```javascript -import Ability from "@ohos.application.Ability"; - -var lifecycleid; - -export default class MainAbility extends Ability { - onCreate() { - console.log("MainAbility onCreate") - let AbilityLifecycleCallback = { - onAbilityCreate(ability){ - console.log("AbilityLifecycleCallback onAbilityCreate ability:" + JSON.stringify(ability)); - }, - onWindowStageCreate(ability, windowStage){ - console.log("AbilityLifecycleCallback onWindowStageCreate ability:" + JSON.stringify(ability)); - console.log("AbilityLifecycleCallback onWindowStageCreate windowStage:" + JSON.stringify(windowStage)); - }, - onWindowStageActive(ability, windowStage){ - console.log("AbilityLifecycleCallback onWindowStageActive ability:" + JSON.stringify(ability)); - console.log("AbilityLifecycleCallback onWindowStageActive windowStage:" + JSON.stringify(windowStage)); - }, - onWindowStageInactive(ability, windowStage){ - console.log("AbilityLifecycleCallback onWindowStageInactive ability:" + JSON.stringify(ability)); - console.log("AbilityLifecycleCallback onWindowStageInactive windowStage:" + JSON.stringify(windowStage)); - }, - onWindowStageDestroy(ability, windowStage){ - console.log("AbilityLifecycleCallback onWindowStageDestroy ability:" + JSON.stringify(ability)); - console.log("AbilityLifecycleCallback onWindowStageDestroy windowStage:" + JSON.stringify(windowStage)); - }, - onAbilityDestroy(ability){ - console.log("AbilityLifecycleCallback onAbilityDestroy ability:" + JSON.stringify(ability)); - }, - onAbilityForeground(ability){ - console.log("AbilityLifecycleCallback onAbilityForeground ability:" + JSON.stringify(ability)); - }, - onAbilityBackground(ability){ - console.log("AbilityLifecycleCallback onAbilityBackground ability:" + JSON.stringify(ability)); - }, - onAbilityContinue(ability){ - console.log("AbilityLifecycleCallback onAbilityContinue ability:" + JSON.stringify(ability)); - } - } - // 1. Obtain applicationContext through the context attribute. - let applicationContext = this.context.getApplicationContext(); - // 2. Use applicationContext to register and listen for the ability lifecycle in the application. - lifecycleid = applicationContext.registerAbilityLifecycleCallback(AbilityLifecycleCallback); - console.log("registerAbilityLifecycleCallback number: " + JSON.stringify(lifecycleid)); - }, - onDestroy() { - let applicationContext = this.context.getApplicationContext(); - applicationContext.unregisterAbilityLifecycleCallback(lifecycleid, (error, data) => { - console.log("unregisterAbilityLifecycleCallback success, err: " + JSON.stringify(error)); - }); - } -} -``` - -**d.ts statement** - -https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ApplicationContext.d.ts - -### application/AbilityStageContext - -**application/AbilityStageContext** is the context for the HAP file. In addition to those provided by the base class **application/Context**, this context contains **HapModuleInfo** and **Configuration**. - -**How to Obtain** - -Obtain the context from the **context** attribute in **AbilityStage**. - -**Example** - -```javascript -export default class MyAbilityStage extends AbilityStage { - onCreate() { - // The context attribute is of the AbilityStageContext type. - console.log('HapModuleInfo is ' + this.context.currentHapModuleInfo); - } -} -``` - -**d.ts statement** - -https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityStageContext.d.ts - -### application/AbilityContext - -In the stage model, each ability has a context attribute. - -**Ability** provides methods to manage the ability lifecycle, and **AbilityContext** provides methods to operate abilities (such as **startAbility** and **connectAbility**). - -**How to Obtain** - -Obtain the context from the **context** attribute in **Ability**. - -**Example** - -```javascript -import Ability from '@ohos.application.Ability' - -export default class MainAbility extends Ability { - onCreate(want, launchParam) { - console.log("[Demo] MainAbility onCreate") - globalThis.abilityWant = want; - } - - onDestroy() { - console.log("[Demo] MainAbility onDestroy") - } - - onWindowStageCreate(windowStage) { - // Set the main page for this ability when the main window is created. - console.log("[Demo] MainAbility onWindowStageCreate") - - // Obtain AbilityContext and print the ability information. - let context = this.context; - console.log("[Demo] MainAbility bundleName " + context.abilityInfo.bundleName) - - windowStage.loadContent("pages/index", (err, data) => { - if (err.code) { - console.error('Failed to load the content. Cause:' + JSON.stringify(err)); - return; - } - console.info('Succeeded in loading the content. Data: ' + JSON.stringify(data)) - }); - } - - onWindowStageDestroy() { - // Release the UI related resources when the main window is destroyed. - console.log("[Demo] MainAbility onWindowStageDestroy") - } - - onForeground() { - // The ability is switched to run in the foreground. - console.log("[Demo] MainAbility onForeground") - } - - onBackground() { - // The ability is switched to run in the background. - console.log("[Demo] MainAbility onBackground") - } -}; -``` - -### application/FormExtensionContext - -For details, see [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md). - -### Obtaining the Context on an ArkTS Page - -In the stage model, in the onWindowStageCreate lifecycle of an ability, you can call **SetUIContent** of **WindowStage** to load an ArkTS page. In some scenarios, you need to obtain the context on the page to call related APIs. - -**How to Obtain** - -Use the API described in the table below to obtain the context associated with an ArkTS page. - -| API | Description | -| :------------------------------------ | :----------------------------------------------------------- | -| getContext(component: Object): Object | Obtains the **Context** object associated with a component on the page.
Since API version 9, this API is supported in ArkTS widgets.| - -**Example** - -```ts -// MainAbility.ts -import Ability from '@ohos.application.Ability' - -export default class MainAbility extends Ability { - onCreate(want, launchParam) { - console.log("[Demo] MainAbility onCreate") - } - - onDestroy() { - console.log("[Demo] MainAbility onDestroy") - } - - onWindowStageCreate(windowStage) { - // Load the index page and pass the current Context object. - windowStage.setUIContent(this.context, "pages/index", null) - } - - onWindowStageDestroy() {} - - onForeground() {} - - onBackground() {} -}; -``` - -```ts -// pages/index.ets -import context from '@ohos.application.context' - -type Context = context.Context - -@Entry -@Component -struct Index { - build() { - Row() { - Column() { - Text('GetContext') - .fontSize(50) - .fontWeight(FontWeight.Bold) - .onClick(() => { - // Obtain the Context object associated with the current component. - var context : Context = getContext(this) as Context - console.info("CacheDir:" + context.cacheDir) - }) - } - .width('100%') - } - .height('100%') - } -} -``` - -## Common Incorrect Usage - -**Error 1: Use globalThis to obtain the context in the stage model.** - -**Reason** - -In the FA model, each ability instance has a JS VM instance. Therefore, a global ability instance can be obtained from the **global** object of the JS engine. In the stage model, where all the processes of an application share a JS VM instance, there is no global ability instance, and using **globalThis** may cause an error or crash. diff --git a/en/application-dev/ability-deprecated/continuationmanager.md b/en/application-dev/ability-deprecated/continuationmanager.md deleted file mode 100644 index 0a7be5da65866f5d1cba16ad3c413161f0f1fb80..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/continuationmanager.md +++ /dev/null @@ -1,277 +0,0 @@ -# ContinuationManager Development - -> **NOTE** -> -> Currently, the **ContinuationManager** module is not available for application development. Its APIs are mainly used to start the device selection module. - -## When to Use -Users are using two or more devices to experience an all-scenario, multi-device lifestyle. Each type of device has its unique advantages and disadvantages specific to scenarios. The ability continuation capability breaks boundaries of devices and enables multi-device collaboration, achieving precise control, universal coordination, and seamless hops of user applications. - -As the entry of the ability continuation capability, **continuationManager** is used to start the device selection module for the user to select the target device. After a device is selected, information about the selected device is returned to the user. The user can then initiate cross-device continuation or collaboration based on the device information. - -![continuationManager](figures/continuationManager.png) - -## Available APIs -| API | Description| -| ---------------------------------------------------------------------------------------------- | ----------- | -| registerContinuation(callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API does not involve any filter parameters and uses an asynchronous callback to return the result.| -| registerContinuation(options: ContinuationExtraParams, callback: AsyncCallback\): void | Registers the continuation management service and obtains a token. This API uses an asynchronous callback to return the result.| -| registerContinuation(options?: ContinuationExtraParams): Promise\ | Registers the continuation management service and obtains a token. This API uses a promise to return the result.| -| on(type: "deviceSelected", token: number, callback: Callback\>): void | Subscribes to device connection events. This API uses an asynchronous callback to return the result.| -| on(type: "deviceUnselected", token: number, callback: Callback\>): void | Subscribes to device disconnection events. This API uses an asynchronous callback to return the result.| -| off(type: "deviceSelected", token: number): void | Unsubscribes from device connection events.| -| off(type: "deviceUnselected", token: number): void | Unsubscribes from device disconnection events.| -| startContinuationDeviceManager(token: number, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API does not involve any filter parameters and uses an asynchronous callback to return the result.| -| startContinuationDeviceManager(token: number, options: ContinuationExtraParams, callback: AsyncCallback\): void | Starts the device selection module to show the list of available devices. This API uses an asynchronous callback to return the result.| -| startContinuationDeviceManager(token: number, options?: ContinuationExtraParams): Promise\ | Starts the device selection module to show the list of available devices. This API uses a promise to return the result.| -| updateContinuationState(token: number, deviceId: string, status: DeviceConnectState, callback: AsyncCallback\): void | Instructs the device selection module to update the device connection state. This API uses an asynchronous callback to return the result.| -| updateContinuationState(token: number, deviceId: string, status: DeviceConnectState): Promise\ | Instructs the device selection module to update the device connection state. This API uses a promise to return the result.| -| unregisterContinuation(token: number, callback: AsyncCallback\): void | Deregisters the continuation management service. This API uses an asynchronous callback to return the result.| -| unregisterContinuation(token: number): Promise\ | Deregisters the continuation management service. This API uses a promise to return the result.| - -## How to Develop -1. Import the **continuationManager** module. - - ```ts - import continuationManager from '@ohos.continuation.continuationManager'; - ``` - -2. Apply for the **DISTRIBUTED_DATASYNC** permission. - - The permission application operation varies according to the ability model in use. In the FA mode, add the required permission in the `config.json` file, as follows: - - ```json - { - "module": { - "reqPermissions": [ - { - "name": "ohos.permission.DISTRIBUTED_DATASYNC" - } - ] - } - } - ``` - - This permission must also be granted by the user through a dialog box when the application is started for the first time. The sample code is as follows: - - ```ts - import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; - import bundle from '@ohos.bundle'; - import featureAbility from '@ohos.ability.featureAbility'; - - async function requestPermission() { - let permissions: Array = [ - "ohos.permission.DISTRIBUTED_DATASYNC" - ]; - let needGrantPermission: boolean = false; - let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); - let applicationInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', 0, 100); - for (let i = 0; i < permissions.length; i++) { - let result = await atManager.verifyAccessToken(applicationInfo.accessTokenId, permissions[i]); - // Check whether the permission is granted. - if (result == abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - needGrantPermission = true; - break; - } - } - // If the permission is not granted, call requestPermissionsFromUser to apply for the permission. - if (needGrantPermission) { - await featureAbility.getContext().requestPermissionsFromUser(permissions, 1); - } else { - console.info('app permission already granted'); - } - } - ``` - - In the stage model, add the required permission in the `module.json5` file. The sample code is as follows: - - ```json - { - "module": { - "requestPermissions": [ - { - "name": "ohos.permission.DISTRIBUTED_DATASYNC" - } - ] - } - } - ``` - - ```ts - import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; - import bundle from '@ohos.bundle'; - - async function requestPermission() { - let permissions: Array = [ - "ohos.permission.DISTRIBUTED_DATASYNC" - ]; - let needGrantPermission: boolean = false; - let atManger: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); - let applicationInfo = await bundle.getApplicationInfo('ohos.samples.continuationmanager', 0, 100); - for (const permission of permissions) { - try { - let grantStatus = await atManger.verifyAccessToken(applicationInfo.accessTokenId, permission); - // Check whether the permission is granted. - if (grantStatus === abilityAccessCtrl.GrantStatus.PERMISSION_DENIED) { - needGrantPermission = true; - break; - } - } catch (err) { - console.error('app permission query grant status error' + JSON.stringify(err)); - needGrantPermission = true; - break; - } - } - // If the permission is not granted, call requestPermissionsFromUser to apply for the permission. - if (needGrantPermission) { - try { - // globalThis.context is Ability.context, which must be assigned a value in the MainAbility.ts file in advance. - await atManger.requestPermissionsFromUser(globalThis.context, permissions); - } catch (err) { - console.error('app permission request permissions error' + JSON.stringify(err)); - } - } else { - console.info('app permission already granted'); - } - } - ``` - -3. Register the continuation management service and obtain a token. - - The sample code is as follows: - - ```ts - let token: number = -1; // Used to save the token returned after the registration. The token will be used when listening for device connection/disconnection events, starting the device selection module, and updating the device connection state. - try { - continuationManager.registerContinuation().then((data) => { - console.info('registerContinuation finished, ' + JSON.stringify(data)); - token = data; // Obtain a token and assign a value to the token variable. - }).catch((err) => { - console.error('registerContinuation failed, cause: ' + JSON.stringify(err)); - }); - } catch (err) { - console.error('registerContinuation failed, cause: ' + JSON.stringify(err)); - } - ``` - -4. Listen for the device connection/disconnection state. - - The sample code is as follows: - - ```ts - let remoteDeviceId: string = ""; // Used to save the information about the remote device selected by the user, which will be used for cross-device continuation or collaboration. - - try { - // The token parameter is the token obtained during the registration. - continuationManager.on("deviceSelected", token, (continuationResults) => { - console.info('registerDeviceSelectedCallback len: ' + continuationResults.length); - if (continuationResults.length <= 0) { - console.info('no selected device'); - return; - } - remoteDeviceId = continuationResults[0].id; // Assign the deviceId of the first selected remote device to the remoteDeviceId variable. - - // Pass the remoteDeviceId parameter to want. - let want = { - deviceId: remoteDeviceId, - bundleName: 'ohos.samples.continuationmanager', - abilityName: 'MainAbility' - }; - globalThis.abilityContext.startAbility(want).then((data) => { - console.info('StartRemoteAbility finished, ' + JSON.stringify(data)); - }).catch((err) => { - console.error('StartRemoteAbility failed, cause: ' + JSON.stringify(err)); - }); - }); - } catch (err) { - console.error('on failed, cause: ' + JSON.stringify(err)); - } - ``` - - The preceding multi-device collaboration operation is performed across devices in the stage model. For details about this operation in the FA model, see [Page Ability Development](fa-pageability.md). - - You can also instruct the device selection module to update the device connection state. The sample code is as follows: - - ```ts - // Set the device connection state. - let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.CONNECTED; - - // The token parameter is the token obtained during the registration, and the remoteDeviceId parameter is the remoteDeviceId obtained. - try { - continuationManager.updateContinuationState(token, remoteDeviceId, deviceConnectStatus).then((data) => { - console.info('updateContinuationState finished, ' + JSON.stringify(data)); - }).catch((err) => { - console.error('updateContinuationState failed, cause: ' + JSON.stringify(err)); - }); - } catch (err) { - console.error('updateContinuationState failed, cause: ' + JSON.stringify(err)); - } - ``` - - Listen for the device disconnection state so that the user can stop cross-device continuation or collaboration in time. The sample code is as follows: - - ```ts - try { - // The token parameter is the token obtained during the registration. - continuationManager.on("deviceUnselected", token, (continuationResults) => { - console.info('onDeviceUnselected len: ' + continuationResults.length); - if (continuationResults.length <= 0) { - console.info('no unselected device'); - return; - } - - // Update the device connection state. - let unselectedDeviceId: string = continuationResults[0].id; // Assign the deviceId of the first deselected remote device to the unselectedDeviceId variable. - let deviceConnectStatus: continuationManager.DeviceConnectState = continuationManager.DeviceConnectState.DISCONNECTING; // Device disconnected. - - // The token parameter is the token obtained during the registration, and the unselectedDeviceId parameter is the unselectedDeviceId obtained. - continuationManager.updateContinuationState(token, unselectedDeviceId, deviceConnectStatus).then((data) => { - console.info('updateContinuationState finished, ' + JSON.stringify(data)); - }).catch((err) => { - console.error('updateContinuationState failed, cause: ' + JSON.stringify(err)); - }); - }); - } catch (err) { - console.error('updateContinuationState failed, cause: ' + JSON.stringify(err)); - } - ``` - -5. Start the device selection module to show the list of available devices on the network. - - The sample code is as follows: - - ```ts - // Filter parameters. - let continuationExtraParams = { - deviceType: ["00E"], // Device type. - continuationMode: continuationManager.ContinuationMode.COLLABORATION_SINGLE // Single-choice mode of the device selection module. - }; - - try { - // The token parameter is the token obtained during the registration. - continuationManager.startContinuationDeviceManager(token, continuationExtraParams).then((data) => { - console.info('startContinuationDeviceManager finished, ' + JSON.stringify(data)); - }).catch((err) => { - console.error('startContinuationDeviceManager failed, cause: ' + JSON.stringify(err)); - }); - } catch (err) { - console.error('startContinuationDeviceManager failed, cause: ' + JSON.stringify(err)); - } - ``` - -6. If you do not need to perform cross-device migration or collaboration operations, you can deregister the continuation management service, by passing the token obtained during the registration. - - The sample code is as follows: - - ```ts - try { - // The token parameter is the token obtained during the registration. - continuationManager.unregisterContinuation(token).then((data) => { - console.info('unregisterContinuation finished, ' + JSON.stringify(data)); - }).catch((err) => { - console.error('unregisterContinuation failed, cause: ' + JSON.stringify(err)); - }); - } catch (err) { - console.error('unregisterContinuation failed, cause: ' + JSON.stringify(err)); - } - ``` diff --git a/en/application-dev/ability-deprecated/fa-brief.md b/en/application-dev/ability-deprecated/fa-brief.md deleted file mode 100644 index 4bdbfa4d7f3c96663cad5e90b9cd0d187a1e8709..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/fa-brief.md +++ /dev/null @@ -1,43 +0,0 @@ -# FA Model Overview - -## Overall Architecture - -Ability is the entry for application development in OpenHarmony. - -The core of ability development is the processing on ability lifecycle callbacks. - -The Feature Ability (FA) model can be used only for application development using API version 8 and earlier versions. In this model, there are PageAbility, ServiceAbility, DataAbility, and FormAbility. -- PageAbility implements the ArkUI and provides the capability for interacting with users. -- ServiceAbility does not have a UI. It runs in the background and provides custom services for other abilities to invoke. -- DataAbility does not have a UI. It runs in the background and enables other abilities to insert, delete, and query data. -- FormAbility is used to implement widgets, a new UI display form available on OpenHarmony devices. - -> Note: Starting from API version 9, the stage model is recommended for application development. - -## Lifecycle - -Among all abilities, PageAbility has the most complex lifecycle, because it has a UI and acts as a touchpoint for interacting with users. -**The following figure shows the lifecycle of PageAbility.** - -![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) - -The other abilities do not involve foreground and background switch or the **onShow** and **onHide** callbacks. -You can override the lifecycle callbacks in **app.js** or **app.ets** to process application logic. - -The **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the callbacks covering the entire lifecycle. - -## Process and Thread Model - -Each application runs in a process. In the FA model, each ability runs in an independent VM. - -When an ability is started, an application process as well as a thread for this ability is created. For an application that has multiple abilities, each ability runs in an independent thread. In the FA model, each ability is bound to an independent VM instance. In this way, abilities are isolated from each other. - -![fa-threading-model](figures/fa-threading-model.png) - -## Application Package Structure - -For details about the project directory structure of the FA model, see [OpenHarmony Project Overview](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-project-overview-0000001218440650#section4154183910141). - -For details about how to configure the application package structure of the FA model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-fa.md). - - diff --git a/en/application-dev/ability-deprecated/fa-dataability.md b/en/application-dev/ability-deprecated/fa-dataability.md deleted file mode 100644 index cc3003eaffb772fdf0dd13c564c019430d016bf1..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/fa-dataability.md +++ /dev/null @@ -1,310 +0,0 @@ -# Data Ability Development - -## When to Use - -A Data ability helps applications manage access to data stored by themselves and other applications. It also provides APIs for sharing data with other applications either on the same device or across devices. - -Data ability providers can customize data access-related APIs such as data inserting, deleting, updating, and querying, as well as file opening, and share data with other applications through these open APIs. - -## URI Introduction - -A Uniform Resource Identifier (URI) is used to identify a specific data item, such as a table in the database or a file on the disk. URIs used in OpenHarmony comply with the commonly used URI standard. A URI consists of the components: - -![fa-dataability-uri](figures/fa-dataability-uri.png) - -- **scheme**: name of the scheme used by the Data ability. The value is fixed at **dataability**. -- **authority**: device ID. To access data on a remote device, set this component to the ID of the remote device. To access data on the local device, leave this component empty. -- **path**: location of the specific resource to access. -- **query**: query parameters. -- **fragment**: subordinate resources to access. - -Example URIs: - -- Cross-device communication: **dataability://***device_id***/***com.domainname.dataability.persondata***/***person***/***10* -- Local-device communication: **dataability:///***com.domainname.dataability.persondata***/***person***/***10* - -> **NOTE** -> -> In the case of local-device communication, **device_id** is empty, and therefore, there are three slashes (/) after **dataability:**. - -## Available APIs - -**Table 1** Data ability lifecycle APIs -|API|Description| -|:------|:------| -|onInitialized(info: AbilityInfo): void|Called during ability initialization to initialize the relational database (RDB).| -|update(uri: string, valueBucket: rdb.ValuesBucket, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Updates data in the database.| -|query(uri: string, columns: Array\, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Queries data in the database.| -|delete(uri: string, predicates: dataAbility.DataAbilityPredicates, callback: AsyncCallback\): void|Deletes one or more data records from the database.| -|normalizeUri(uri: string, callback: AsyncCallback\): void|Normalizes the URI. A normalized URI applies to cross-device use, persistence, backup, and restore. When the context changes, it ensures that the same data item can be referenced.| -|batchInsert(uri: string, valueBuckets: Array\, callback: AsyncCallback\): void|Inserts multiple data records into the database.| -|denormalizeUri(uri: string, callback: AsyncCallback\): void|Converts a normalized URI generated by **normalizeUri** into a denormalized URI.| -|insert(uri: string, valueBucket: rdb.ValuesBucket, callback: AsyncCallback\): void|Inserts a data record into the database.| -|openFile(uri: string, mode: string, callback: AsyncCallback\): void|Opens a file.| -|getFileTypes(uri: string, mimeTypeFilter: string, callback: AsyncCallback\>): void|Obtains the MIME type of a file.| -|getType(uri: string, callback: AsyncCallback\): void|Obtains the MIME type matching the data specified by the URI.| -|executeBatch(ops: Array\, callback: AsyncCallback\>): void|Operates data in the database in batches.| -|call(method: string, arg: string, extras: PacMap, callback: AsyncCallback\): void|Calls a custom API.| - - -## How to Develop -### Creating a Data Ability - -1. To meet the basic requirements of the database storage service, implement the **Insert**, **Query**, **Update**, and **Delete** APIs in the **Data** class. The **BatchInsert** and **ExecuteBatch** APIs have already implemented the traversal logic, but not batch data processing. - - The following code snippet shows how to create a Data ability: - - ```javascript - import featureAbility from '@ohos.ability.featureAbility' - import dataAbility from '@ohos.data.dataAbility' - import dataRdb from '@ohos.data.rdb' - - const TABLE_NAME = 'book' - const STORE_CONFIG = { name: 'book.db' } - const SQL_CREATE_TABLE = 'CREATE TABLE IF NOT EXISTS book(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, introduction TEXT NOT NULL)' - let rdbStore: dataRdb.RdbStore = undefined - - export default { - onInitialized(abilityInfo) { - console.info('DataAbility onInitialized, abilityInfo:' + abilityInfo.bundleName) - let context = featureAbility.getContext() - dataRdb.getRdbStore(context, STORE_CONFIG, 1, (err, store) => { - console.info('DataAbility getRdbStore callback') - store.executeSql(SQL_CREATE_TABLE, []) - rdbStore = store - }); - }, - insert(uri, valueBucket, callback) { - console.info('DataAbility insert start') - rdbStore.insert(TABLE_NAME, valueBucket, callback) - }, - batchInsert(uri, valueBuckets, callback) { - console.info('DataAbility batch insert start') - for (let i = 0;i < valueBuckets.length; i++) { - console.info('DataAbility batch insert i=' + i) - if (i < valueBuckets.length - 1) { - rdbStore.insert(TABLE_NAME, valueBuckets[i], (err: any, num: number) => { - console.info('DataAbility batch insert ret=' + num) - }) - } else { - rdbStore.insert(TABLE_NAME, valueBuckets[i], callback) - } - } - }, - query(uri, columns, predicates, callback) { - console.info('DataAbility query start') - let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) - rdbStore.query(rdbPredicates, columns, callback) - }, - update(uri, valueBucket, predicates, callback) { - console.info('DataAbilityupdate start') - let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) - rdbStore.update(valueBucket, rdbPredicates, callback) - }, - delete(uri, predicates, callback) { - console.info('DataAbilitydelete start') - let rdbPredicates = dataAbility.createRdbPredicates(TABLE_NAME, predicates) - rdbStore.delete(rdbPredicates, callback) - } - }; - ``` - -2. Configure the submodule. - - | JSON Field| Description | - | ------------ | ------------------------------------------------------------ | - | "name" | Ability name, corresponding to the **Data** class name derived from **Ability**. | - | "type" | Ability type, which is **Data** for a Data ability. | - | "uri" | URI used for communication. | - | "exported" | Whether the Data ability is visible to other applications. When this parameter is set to **true**, the Data ability can communicate with other applications.| - - **config.json configuration example** - - ```json - "abilities":[{ - "srcPath": "DataAbility", - "name": ".DataAbility", - "icon": "$media:icon", - "srcLanguage": "ets", - "description": "$string:description_dataability", - "type": "data", - "exported": true, - "uri": "dataability://ohos.samples.etsdataability.DataAbility" - }] - ``` - -### Accessing a Data ability -#### Development Preparations - -Import the basic dependency packages and obtain the URI string for communicating with the Data submodule. - -The basic dependency packages include: -- @ohos.ability.featureAbility -- @ohos.data.dataAbility -- @ohos.data.rdb - -#### Data Ability API Development - - -1. Create a Data ability helper. - - For details about the APIs provided by **DataAbilityHelper**, see [DataAbilityHelper Module](../reference/apis/js-apis-inner-ability-dataAbilityHelper.md). - ```js - // Different from the URI defined in the config.json file, the URI passed in the parameter has an extra slash (/), because there is a DeviceID parameter between the second and the third slash (/). - import featureAbility from '@ohos.ability.featureAbility' - import ohos_data_ability from '@ohos.data.dataAbility' - import ohos_data_rdb from '@ohos.data.rdb' - - var urivar = "dataability:///com.ix.DataAbility" - var DAHelper = featureAbility.acquireDataAbilityHelper( - urivar - ); - ``` -2. Construct RDB data. - ```js - var valuesBucket = {"name": "gaolu"} - var da = new ohos_data_ability.DataAbilityPredicates() - var valArray =new Array("value1"); - var cars = new Array({"batchInsert1" : "value1",}); - ``` -3. Use **insert** to insert data to the Data submodule. - ```js - // Callback mode: - DAHelper.insert( - urivar, - valuesBucket, - (error, data) => { - console.log("DAHelper insert result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var datainsert = await DAHelper.insert( - urivar, - valuesBucket - ); - ``` -4. Use **delete** to delete data from the Data submodule. - ```js - // Callback mode: - DAHelper.delete( - urivar, - da, - (error, data) => { - console.log("DAHelper delete result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var datadelete = await DAHelper.delete( - urivar, - da, - ); - ``` -5. Use **update** to update data in the Data submodule. - ```js - // Callback mode: - DAHelper.update( - urivar - valuesBucket, - da, - (error, data) => { - console.log("DAHelper update result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var dataupdate = await DAHelper.update( - urivar, - valuesBucket, - da, - ); - ``` -6. Use **query** to query data in the Data submodule. - ```js - // Callback mode: - DAHelper.query( - urivar, - valArray, - da, - (error, data) => { - console.log("DAHelper query result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var dataquery = await DAHelper.query( - urivar, - valArray, - da - ); - ``` -7. Use **batchInsert** to insert data in batches to the Data submodule. - ```js - // Callback mode: - DAHelper.batchInsert( - urivar, - cars, - (error, data) => { - console.log("DAHelper batchInsert result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var databatchInsert = await DAHelper.batchInsert( - urivar, - cars - ); - ``` -8. Use **executeBatch** to process data in batches in the Data submodule. - ```js - // Callback mode: - DAHelper.executeBatch( - urivar, - [ - { - uri: urivar, - type: featureAbility.DataAbilityOperationType.TYPE_INSERT, - valuesBucket: {"executeBatch" : "value1",}, - predicates: da, - expectedCount:0, - predicatesBackReferences: null, - interrupted:true, - } - ], - (error, data) => { - console.log("DAHelper executeBatch result: " + data) - } - ); - ``` - - ```js - // Promise mode: - var dataexecuteBatch = await DAHelper.executeBatch( - urivar, - [ - { - uri: urivar, - type: featureAbility.DataAbilityOperationType.TYPE_INSERT, - valuesBucket: - { - "executeBatch" : "value1", - }, - predicates: da, - expectedCount:0, - predicatesBackReferences: null, - interrupted:true, - } - ] - ); - ``` diff --git a/en/application-dev/ability-deprecated/fa-formability.md b/en/application-dev/ability-deprecated/fa-formability.md deleted file mode 100644 index 4302e8d83c4b2cc6585de29b6bdaa3504c671527..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/fa-formability.md +++ /dev/null @@ -1,404 +0,0 @@ -# FA Widget Development - -## Widget Overview -A widget is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. - -A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message. - -Before you get started, it would be helpful if you have a basic understanding of the following concepts: -- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users. -- Widget host: an application that displays the widget content and controls the widget location. -- Widget Manager: a resident agent that provides widget management features such as periodic widget updates. - -> **NOTE** -> -> The widget host and provider do not need to be running all the time. The Widget Manager will start the widget provider to obtain widget information when a widget is added, deleted, or updated. - -You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager. - -The widget provider controls the widget content to display, the layout of components used in the widget, and click events bound to the components. - -## Development Overview - -Carry out the following operations to develop the widget provider based on the [FA model](fa-brief.md): - -1. Implement lifecycle callbacks by using the **LifecycleForm** APIs. -2. Create a **FormBindingData** instance. -3. Update a widget by using the **FormProvider** APIs. -4. Develop the widget UI page. - -## Available APIs - -The table below describes the **LifecycleForm** APIs, which represent the lifecycle callbacks of a widget (known as a **Form** instance). - -**Table 1** LifecycleForm APIs - -| API | Description | -| :----------------------------------------------------------- | :------------------------------------------- | -| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created. | -| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.| -| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. | -| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. | -| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. | -| onDestroy(formId: string): void | Called to notify the widget provider that a widget has been destroyed. | -| onAcquireFormState?(want: Want): formInfo.FormState | Called to instruct the widget provider to receive the status query result of a widget. | - -The table below describes the **FormProvider** APIs. For details, see [FormProvider](../reference/apis/js-apis-application-formProvider.md). - -**Table 2** FormProvider APIs - -| API | Description | -| :----------------------------------------------------------- | :------------------------------------------------ | -| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. | -| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.| -| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. | -| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. | - -## How to Develop - -### Implementing Lifecycle Callbacks - -To create an FA widget, you need to implement lifecycle callbacks using the **LifecycleForm** APIs. The sample code is as follows: - -1. Import the required modules. - - ```javascript - import formBindingData from '@ohos.application.formBindingData' - import formInfo from '@ohos.application.formInfo' - import formProvider from '@ohos.application.formProvider' - ``` - -2. Implement lifecycle callbacks for the widget. - - ```javascript - export default { - onCreate(want) { - console.log('FormAbility onCreate'); - // Persistently store widget information for subsequent use, such as widget instance retrieval or update. - let obj = { - "title": "titleOnCreate", - "detail": "detailOnCreate" - }; - let formData = formBindingData.createFormBindingData(obj); - return formData; - }, - onCastToNormal(formId) { - // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion. - console.log('FormAbility onCastToNormal'); - }, - onUpdate(formId) { - // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. - console.log('FormAbility onUpdate'); - let obj = { - "title": "titleOnUpdate", - "detail": "detailOnUpdate" - }; - let formData = formBindingData.createFormBindingData(obj); - formProvider.updateForm(formId, formData).catch((error) => { - console.log('FormAbility updateForm, error:' + JSON.stringify(error)); - }); - }, - onVisibilityChange(newStatus) { - // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification. - console.log('FormAbility onVisibilityChange'); - }, - onEvent(formId, message) { - // If the widget supports event triggering, override this method and implement the trigger. - console.log('FormAbility onEvent'); - }, - onDestroy(formId) { - // Delete widget data. - console.log('FormAbility onDestroy'); - }, - onAcquireFormState(want) { - console.log('FormAbility onAcquireFormState'); - return formInfo.FormState.READY; - }, - } - ``` - -### Configuring the Widget Configuration File - -The widget configuration file is named **config.json**. Find the **config.json** file for the widget and edit the file depending on your need. - -- The **js** module in the **config.json** file provides JavaScript resources of the widget. The internal structure is described as follows: - - | Field| Description | Data Type| Default | - | -------- | ------------------------------------------------------------ | -------- | ------------------------ | - | name | Name of a JavaScript component. The default value is **default**. | String | No | - | pages | Route information about all pages in the JavaScript component, including the page path and page name. The value is an array, in which each element represents a page. The first element in the array represents the home page of the JavaScript FA.| Array | No | - | window | Window-related configurations. | Object | Yes | - | type | Type of the JavaScript component.
**normal**: indicates an application instance.
**form**: indicates a widget instance.| String | Yes (initial value: **normal**)| - | mode | Development mode of the JavaScript component. | Object | Yes (initial value: left empty) | - - Example configuration: - - ```json - "js": [{ - "name": "widget", - "pages": ["pages/index/index"], - "window": { - "designWidth": 720, - "autoDesignWidth": true - }, - "type": "form" - }] - ``` - -- The **abilities** module in the **config.json** file corresponds to **LifecycleForm** of the widget. The internal structure is described as follows: - - | Field | Description | Data Type | Default | - | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ | - | name | Class name of the widget. The value is a string with a maximum of 127 bytes. | String | No | - | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) | - | isDefault | Whether the widget is a default one. Each ability has only one default widget.
**true**: The widget is the default one.
**false**: The widget is not the default one.| Boolean | No | - | type | Type of the widget.
**JS**: indicates a JavaScript-programmed widget. | String | No | - | colorMode | Color mode of the widget.
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)| - | supportDimensions | Grid styles supported by the widget.
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| No | - | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No | - | updateEnabled | Whether the widget can be updated periodically.
**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.
**false**: The widget cannot be updated periodically.| Boolean | No | - | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) | - | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.
If the value is **0**, this field does not take effect.
If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) | - | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) | - | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) | - | jsComponentName | Component name of the widget. The value is a string with a maximum of 127 bytes. | String | No | - | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) | - | customizeData | Custom information about the widget. | Object array | Yes (initial value: left empty) | - - Example configuration: - - ```json - "abilities": [{ - "name": "FormAbility", - "description": "This is a FormAbility", - "formsEnabled": true, - "icon": "$media:icon", - "label": "$string:form_FormAbility_label", - "srcPath": "FormAbility", - "type": "service", - "srcLanguage": "ets", - "formsEnabled": true, - "forms": [{ - "colorMode": "auto", - "defaultDimension": "2*2", - "description": "This is a widget.", - "formVisibleNotify": true, - "isDefault": true, - "jsComponentName": "widget", - "name": "widget", - "scheduledUpdateTime": "10:30", - "supportDimensions": ["2*2"], - "type": "JS", - "updateEnabled": true - }] - }] - ``` - - -### Persistently Storing Widget Data - -A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. - -```javascript - onCreate(want) { - console.log('FormAbility onCreate'); - - let formId = want.parameters["ohos.extra.param.key.form_identity"]; - let formName = want.parameters["ohos.extra.param.key.form_name"]; - let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"]; - // Persistently store widget data for subsequent use, such as widget instance retrieval or update. - // The storeFormInfo API is not implemented here. - storeFormInfo(formId, formName, tempFlag, want); - - let obj = { - "title": "titleOnCreate", - "detail": "detailOnCreate" - }; - let formData = formBindingData.createFormBindingData(obj); - return formData; - } -``` - -You should override **onDestroy** to implement widget data deletion. - -```javascript - onDestroy(formId) { - console.log('FormAbility onDestroy'); - - // You need to implement the code for deleting the persistent widget data. - // The deleteFormInfo API is not implemented here. - deleteFormInfo(formId); - } -``` - -For details about how to implement persistent data storage, see [Data Persistence by User Preferences](../database/data-persistence-by-preferences.md). - -The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. - -- Normal widget: a widget persistently used by the widget host - -- Temporary widget: a widget temporarily used by the widget host - -Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake. - -### Updating Widget Data - -When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows: - -```javascript -onUpdate(formId) { - // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. - console.log('FormAbility onUpdate'); - let obj = { - "title": "titleOnUpdate", - "detail": "detailOnUpdate" - }; - let formData = formBindingData.createFormBindingData(obj); - // Call the updateForm() method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged. - formProvider.updateForm(formId, formData).catch((error) => { - console.log('FormAbility updateForm, error:' + JSON.stringify(error)); - }); -} -``` - -### Developing the Widget UI Page - -You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget. - -> **NOTE** -> -> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI. - - - HML file: - ```html -
- -
- -
-
- {{title}} - {{detail}} -
-
-
- ``` - - - CSS file: - - ```css -.container { - flex-direction: column; - justify-content: center; - align-items: center; -} - -.bg-img { - flex-shrink: 0; - height: 100%; -} - -.container-inner { - flex-direction: column; - justify-content: flex-end; - align-items: flex-start; - height: 100%; - width: 100%; - padding: 12px; -} - -.title { - font-size: 19px; - font-weight: bold; - color: white; - text-overflow: ellipsis; - max-lines: 1; -} - -.detail_text { - font-size: 16px; - color: white; - opacity: 0.66; - text-overflow: ellipsis; - max-lines: 1; - margin-top: 6px; -} - ``` - - - JSON file: - ```json - { - "data": { - "title": "TitleDefault", - "detail": "TextDefault" - }, - "actions": { - "routerEvent": { - "action": "router", - "abilityName": "com.example.entry.MainAbility", - "params": { - "message": "add detail" - } - } - } - } - ``` - -Now you've got a widget shown below. - -![fa-form-example](figures/fa-form-example.png) - -### Developing Widget Events - -You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows: - -1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. -2. Set the router event. - - **action**: **"router"**, which indicates a router event. - - **abilityName**: target ability name, for example, **com.example.entry.MainAbility**, which is the default main ability name in DevEco Studio for the FA model. - - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the FA model, **featureAbility.getWant()** can be used to obtain **want** and its **parameters** field. -3. Set the message event. - - **action**: **"message"**, which indicates a message event. - - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**. - -The code snippet is as follows: - - - HML file: - ```html -
- -
- -
-
- {{title}} - {{detail}} -
-
-
- ``` - - - JSON file: - ```json - { - "data": { - "title": "TitleDefault", - "detail": "TextDefault" - }, - "actions": { - "routerEvent": { - "action": "router", - "abilityName": "com.example.entry.MainAbility", - "params": { - "message": "add detail" - } - }, - "messageEvent": { - "action": "message", - "params": { - "message": "add detail" - } - } - } - } - ``` diff --git a/en/application-dev/ability-deprecated/fa-pageability.md b/en/application-dev/ability-deprecated/fa-pageability.md deleted file mode 100644 index 4af75cc8448516f338d1da31d6a5ec8c68f97b11..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/fa-pageability.md +++ /dev/null @@ -1,224 +0,0 @@ -# Page Ability Development - -## Overview - -### Concepts - -The Page ability implements the ArkUI and provides the capability of interacting with developers. When you create an ability in DevEco Studio, DevEco Studio automatically creates template code. - -The capabilities related to the Page ability are implemented through the **featureAbility**, and the lifecycle callbacks are implemented through the callbacks in **app.js** or **app.ets**. - -### Page Ability Lifecycle - -Introduction to the Page ability lifecycle: - -The Page ability lifecycle defines all states of a Page ability, such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**. - -The following figure shows the lifecycle state transition of the Page ability. - -![PageAbility-Lifecycle](figures/page-ability-lifecycle.png) - - -Description of ability lifecycle states: - - - **UNINITIALIZED**: The Page ability is not initialized. This is a temporary state, from which a Page ability changes directly to the **INITIAL** state upon its creation. - - - **INITIAL**: The Page ability is initialized but not running. The Page ability enters the **INACTIVE** state after it is started. - - - **INACTIVE**: The Page ability is visible but does not gain focus. - - - **ACTIVE**: The Page ability runs in the foreground and has focus. - - - **BACKGROUND**: The Page ability runs in the background. After being re-activated, the Page ability enters the **ACTIVE** state. After being destroyed, the Page ability enters the **INITIAL** state. - -The following figure shows the relationship between lifecycle callbacks and lifecycle states of the Page ability. - -![fa-pageAbility-lifecycle](figures/fa-pageAbility-lifecycle.png) - -You can override the lifecycle callbacks provided by the Page ability in the **app.js** or **app.ets** file. Currently, the **app.js** file provides only the **onCreate** and **onDestroy** callbacks, and the **app.ets** file provides the full lifecycle callbacks. - -### Launch Type - -The ability supports two launch types: singleton and multi-instance. - -You can specify the launch type by setting **launchType** in the **config.json** file. - -**Table 1** Startup modes - -| Launch Type | Description |Description | -| ----------- | ------- |---------------- | -| standard | Multi-instance | A new instance is started each time an ability starts.| -| singleton | Singleton | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| - -By default, **singleton** is used. - - -## Development Guidelines - -### Available APIs - -**Table 2** APIs provided by featureAbility - -| API | Description | -| --------------------------------------------------- | --------------- | -| void startAbility(parameter: StartAbilityParameter) | Starts an ability. | -| Context getContext(): | Obtains the application context.| -| void terminateSelf() | Terminates the ability. | -| bool hasWindowFocus() | Checks whether the ability has focus. | - - -### Starting a Local Page Ability - -**Modules to Import** - -```js - import featureAbility from '@ohos.ability.featureAbility' -``` - -**Example** - -```javascript - import featureAbility from '@ohos.ability.featureAbility' - featureAbility.startAbility({ - want: { - action: "", - entities: [""], - type: "", - deviceId: "", - bundleName: "com.example.myapplication", - /* In the FA model, abilityName consists of package and ability name. */ - abilityName: "com.example.entry.secondAbility", - uri: "" - } - }); -``` - -### Starting a Remote Page Ability ->NOTE -> ->This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. - -**Modules to Import** - -``` - import featureAbility from '@ohos.ability.featureAbility' - import deviceManager from '@ohos.distributedHardware.deviceManager'; -``` - -**Example** -```ts - function onStartRemoteAbility() { - console.info('onStartRemoteAbility begin'); - let params; - let wantValue = { - bundleName: 'ohos.samples.etsDemo', - abilityName: 'ohos.samples.etsDemo.RemoteAbility', - deviceId: getRemoteDeviceId(), - parameters: params - }; - console.info('onStartRemoteAbility want=' + JSON.stringify(wantValue)); - featureAbility.startAbility({ - want: wantValue - }).then((data) => { - console.info('onStartRemoteAbility finished, ' + JSON.stringify(data)); - }); - console.info('onStartRemoteAbility end'); - } -``` - -Obtain **deviceId** from **DeviceManager**. The sample code is as follows: - -```ts - import deviceManager from '@ohos.distributedHardware.deviceManager'; - let dmClass; - function getRemoteDeviceId() { - if (typeof dmClass === 'object' && dmClass != null) { - let list = dmClass.getTrustedDeviceListSync(); - if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { - console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); - return; - } - console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); - return list[0].deviceId; - } else { - console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); - } - } -``` - -In the cross-device scenario, the application must also apply for the data synchronization permission from end users. The sample code is as follows: - -```ts - import abilityAccessCtrl from "@ohos.abilityAccessCtrl"; - import bundle from '@ohos.bundle'; - async function RequestPermission() { - console.info('RequestPermission begin'); - let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"]; - let bundleFlag = 0; - let tokenID = undefined; - let userID = 100; - let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); - tokenID = appInfo.accessTokenId; - let atManager = abilityAccessCtrl.createAtManager(); - let requestPermissions: Array = []; - for (let i = 0;i < array.length; i++) { - let result = await atManager.verifyAccessToken(tokenID, array[i]); - console.info("verifyAccessToken result:" + JSON.stringify(result)); - if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - requestPermissions.push(array[i]); - } - } - console.info("requestPermissions:" + JSON.stringify(requestPermissions)); - if (requestPermissions.length == 0 || requestPermissions == []) { - return; - } - let context = featureAbility.getContext(); - context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ - console.info("data:" + JSON.stringify(data)); - console.info("data requestCode:" + data.requestCode); - console.info("data permissions:" + data.permissions); - console.info("data authResults:" + data.authResults); - }); - console.info('RequestPermission end'); - } -``` - -### Lifecycle APIs - -**Table 3** Lifecycle callbacks - -| API | Description | -| ------------ | ------------------------------------------------------------ | -| onShow() | Called when the ability is switched from the background to the foreground. In this case, the ability is visible to users.| -| onHide() | Called when the ability is switched from the foreground to the background. In this case, the ability is invisible to users.| -| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for application exit, such as recycling resources and clearing the cache.| -| onCreate() | Called when the ability is created for the first time. You can initialize the application in this callback.| -| onInactive() | Called when the ability loses focus. An ability loses focus when it is about to enter the background state.| -| onActive() | Called when the ability is switched to the foreground and gains focus. | - -**Example** - -You need to override the lifecycle callbacks except **onCreate()** and **onDestroy()** in **app.js** or **app.ets**. The **onCreate()** and **onDestroy()** callbacks are automatically generated in the template code provided by DevEco Studio. - -```javascript -export default { - onCreate() { - console.info('Application onCreate') - }, - onDestroy() { - console.info('Application onDestroy') - }, - onShow(){ - console.info('Application onShow') - }, - onHide(){ - console.info('Application onHide') - }, - onInactive(){ - console.info('Application onInactive') - }, - onActive(){ - console.info('Application onActive') - }, -} -``` diff --git a/en/application-dev/ability-deprecated/fa-serviceability.md b/en/application-dev/ability-deprecated/fa-serviceability.md deleted file mode 100644 index 0c2a65aebf1076e739009101980633e41f77e8a7..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/fa-serviceability.md +++ /dev/null @@ -1,333 +0,0 @@ -# Service Ability Development - -## When to Use -A Service ability is used to run tasks in the background, such as playing music or downloading files. It does not provide a UI for user interaction. Service abilities can be started by other applications or abilities and can keep running in the background even after the user switches to another application. - -## Lifecycle APIs - -**Table 1** Service ability lifecycle APIs -|API|Description| -|:------|:------| -|onStart?(): void|Called to initialize a Service ability when the Service ability is being created. This callback is invoked only once in the entire lifecycle of a Service ability.| -|onCommand?(want: Want, startId: number): void|Called every time a Service ability is created on the client. You can collect calling statistics and perform initialization operations in this callback.| -|onConnect?(want: Want): rpc.RemoteObject|Called when another ability is connected to the Service ability.| -|onDisconnect?(want: Want): void|Called when another ability is disconnected from the Service ability.| -|onStop?(): void|Called when the Service ability is being destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners.| - -The differences between **onCommand()** and **onConnect()** are as follows: - - The **onCommand()** callback is triggered each time the client starts the Service ability by calling **startAbility** or **startAbilityForResult**. - - The **onConnect()** callback is triggered each time the client establishes a new connection with the Service ability by calling **connectAbility**. - -## How to Develop - -### Creating and Registering a Service Ability - -1. Override the Service ability-related lifecycle callbacks to implement your own logic for processing interaction requests. - - ```ts - export default { - onStart() { - console.log('ServiceAbility onStart'); - }, - onCommand(want, startId) { - console.log('ServiceAbility onCommand'); - }, - onConnect(want) { - console.log('ServiceAbility OnConnect'); - // Below lists the implementation of ServiceAbilityStub. - return new ServiceAbilityStub('test'); - }, - onDisconnect(want) { - console.log('ServiceAbility OnDisConnect'); - }, - onStop() { - console.log('ServiceAbility onStop'); - } - } - ``` - -2. Register a Service ability. - - Declare the Service ability in the **config.json** file by setting its **type** attribute to **service**. - - ```json - { - "module": { - "abilities": [ - { - "name": ".ServiceAbility", - "type": "service", - "visible": true - ... - } - ] - ... - } - ... - } - ``` - - - -### Starting a Service Ability - -The **Ability** class provides the **startAbility()** API for you to start another Service ability by passing a **Want** object. - -To set information about the target Service ability, you can first construct a **Want** object with the **bundleName** and **abilityName** parameters specified. - -- **bundleName** specifies the bundle name of the target application. -- **abilityName** specifies the target ability name. - -The following code snippet shows how to start a Service ability running on the local device: - -```ts -import featureAbility from '@ohos.ability.featureAbility' - -featureAbility.startAbility( - { - want: - { - bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility" - } - } -).then((err) => { - console.log("startService success"); -}).catch (err => { - console.log("startService FAILED"); -}); -``` - -In the preceding code, the **startAbility()** API is used to start the Service ability. -- If the Service ability is not running, the system initializes the Service ability, and calls **onStart()** and **onCommand()** on the Service ability in sequence. -- If the Service ability is running, the system directly calls **onCommand()** on the Service ability. - -The following code snippet shows how to start a Service ability running on the remote device. For details, see [Connecting to a Remote Service Ability](#connecting-to-a-remote-service-ability). - -```ts -import featureAbility from '@ohos.ability.featureAbility' - -featureAbility.startAbility( - { - want: - { - deviceId: remoteDeviceId, // Remote device ID. - bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility" - } - } -).then((err) => { - console.log("startService success"); -}).catch (err => { - console.log("startService FAILED"); -}); -``` - - -### Stopping a Service Ability - - In normal cases, a Service ability can be stopped by itself or by the system. - - The Service ability can call **particleAbility.terminateSelf()** to stop itself. - - If the application process where the Service ability is located exits, the Service ability is reclaimed along with the process. - - If the Service ability is only accessed through **connectAbility()** (the **onCommand()** callback has never been triggered), the system stops the Service ability when the last connection to the Service ability is disconnected. - -### Connecting to a Local Service Ability - -If a Service ability wants to interact with a Page ability or a Service ability in another application, you must first create a connection. A Service ability allows other abilities to connect to it through **connectAbility()**. - - -You can use either of the following methods to connect to a Service ability: - -1. Using the IDL to automatically generate code - - Use OpenHarmony Interface Definition Language (IDL) to automatically generate the corresponding client, server, and **IRemoteObject** code. For details, see [Development Using TS](../IDL/idl-guidelines.md#development-using-ts). - -2. Writing code in the corresponding file - - When using **connectAbility()**, pass the **Want** and **ConnectOptions** objects of the target Service ability, where **ConnectOptions** encapsulates the following three callbacks that need to be implemented. - - **onConnect()**: callback used for processing when the Service ability is connected. - - **onDisconnect()**: callback used for processing when the Service ability is disconnected. - - **onFailed()**: callback used for processing when the connection to the Service ability fails. - - The following code snippet shows how to implement the callbacks: - - ```ts - import prompt from '@system.prompt' - - var option = { - onConnect: function onConnectCallback(element, proxy) { - console.log(`onConnectLocalService onConnectDone`); - if (proxy === null) { - prompt.showToast({ - message: "Connect service failed" - }); - return; - } - // After obtaining the proxy of the Service ability, the calling ability can communicate with the Service ability. - let data = rpc.MessageParcel.create(); - let reply = rpc.MessageParcel.create(); - let option = new rpc.MessageOption(); - data.writeString("InuptString"); - proxy.sendRequest(0, data, reply, option); - prompt.showToast({ - message: "Connect service success" - }); - }, - onDisconnect: function onDisconnectCallback(element) { - console.log(`onConnectLocalService onDisconnectDone element:${element}`); - prompt.showToast({ - message: "Disconnect service success" - }); - }, - onFailed: function onFailedCallback(code) { - console.log(`onConnectLocalService onFailed errCode:${code}`); - prompt.showToast({ - message: "Connect local service onFailed" - }); - } - }; - ``` - - The following code snippet shows how to connect to a local Service ability: - - ```ts - import featureAbility from '@ohos.ability.featureAbility' - - let want = { - bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility" - }; - let connectId = featureAbility.connectAbility(want, option); - ``` - - When a Service ability is connected, the **onConnect()** callback is invoked and returns an **IRemoteObject** defining the proxy used for communicating with the Service ability. OpenHarmony provides the default implementation of **IRemoteObject**. You can inherit **rpc.RemoteObject** to create a custom implementation class for interaction with the Service ability. For details, see the [RPC API Reference](..\reference\apis\js-apis-rpc.md). - - The following code snippet shows how the Service ability returns itself to the calling ability: - - ```ts - import rpc from "@ohos.rpc" - - class ServiceAbilityStub extends rpc.RemoteObject { - constructor(des: any) { - if (typeof des === 'string') { - super(des); - } else { - console.log("Error, the input param is not string"); - return; - } - } - - onRemoteRequest(code: number, data: any, reply: any, option: any) { - console.log("onRemoteRequest called"); - // Execute the service logic. - if (code === 1) { - // Sort the input strings. - let string = data.readString(); - console.log(`Input string = ${string}`); - let result = Array.from(string).sort().join(''); - console.log(`Output result = ${result}`); - reply.writeString(result); - } else { - console.log(`Unknown request code`); - } - return true; - } - } - - export default { - onStart() { - console.log('ServiceAbility onStart'); - }, - onCommand(want, startId) { - console.log('ServiceAbility onCommand'); - }, - onConnect(want) { - console.log('ServiceAbility OnConnect'); - return new ServiceAbilityStub('ServiceAbilityRemoteObject'); - }, - onDisconnect(want) { - console.log('ServiceAbility OnDisConnect'); - }, - onStop() { - console.log('ServiceAbility onStop'); - } - } - ``` - -### Connecting to a Remote Service Ability - -This feature applies only to system applications. The method of creating a **ConnectOptions** object for connecting to a remote Service ability is similar to that for connecting to a local Service ability. The differences are as follows: - - The application must apply for the data synchronization permission from the user. - - **Want** of the target Service ability must contain the remote device ID. - -> **NOTE** -> -> The **getTrustedDeviceList** API of **DeviceManager** is open only to system applications. Currently, only system applications can connect to a remote Service ability. -> -> For details about the API definition, see [Device Management](..\reference\apis\js-apis-device-manager.md). - -The data synchronization permission is required in the cross-device scenario. Configure the permission in the **config.json** file. - -```json -{ - ... - "module": { - ... - "reqPermissions": [{ - "name": "ohos.permission.DISTRIBUTED_DATASYNC" - }] - } -} -``` - -The **DISTRIBUTED_DATASYNC** permission is user granted. Therefore, your application, when being started, must display a dialog box to request the permission. The sample code is as follows: - -```ts -import abilityAccessCtrl from "@ohos.abilityAccessCtrl" -import bundle from '@ohos.bundle' - -async function RequestPermission() { - console.info('RequestPermission begin'); - let array: Array = ["ohos.permission.DISTRIBUTED_DATASYNC"]; - let bundleFlag = 0; - let tokenID = undefined; - let userID = 100; - let appInfo = await bundle.getApplicationInfo('ohos.samples.etsDemo', bundleFlag, userID); - tokenID = appInfo.accessTokenId; - let atManager = abilityAccessCtrl.createAtManager(); - let requestPermissions: Array = []; - for (let i = 0;i < array.length; i++) { - let result = await atManager.verifyAccessToken(tokenID, array[i]); - console.info("verifyAccessToken result:" + JSON.stringify(result)); - if (result != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) { - requestPermissions.push(array[i]); - } - } - console.info("requestPermissions:" + JSON.stringify(requestPermissions)); - if (requestPermissions.length == 0 || requestPermissions == []) { - return; - } - let context = featureAbility.getContext(); - context.requestPermissionsFromUser(requestPermissions, 1, (data)=>{ - console.info("data:" + JSON.stringify(data)); - }); - console.info('RequestPermission end'); -} -``` - -To obtain the device ID, import the **@ohos.distributedHardware.deviceManager** module, which provides **getTrustedDeviceList** to obtain the remote device ID. For details about how to use the API, see [Device Management](..\reference\apis\js-apis-device-manager.md). - -To connect to a remote Service ability, you only need to define **deviceId** in **Want**. The sample code is as follows: - -```ts -import featureAbility from '@ohos.ability.featureAbility' - -let want = { - deviceId: remoteDeviceId, - bundleName: "com.jstest.service", - abilityName: "com.jstest.service.ServiceAbility" -}; -let connectId = featureAbility.connectAbility(want, option); -``` - -The other implementations are the same as those for the connection to a local Service ability. For details, see the sample code provided under [Connecting to a Local Service Ability](#connecting-to-a-local-service-ability). diff --git a/en/application-dev/ability-deprecated/figures/AbilityComponentInstanceMission.png b/en/application-dev/ability-deprecated/figures/AbilityComponentInstanceMission.png deleted file mode 100644 index ce349b7a3544739dd2d3314d35f5b8e3ee68357c..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/AbilityComponentInstanceMission.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/ExtensionAbility.png b/en/application-dev/ability-deprecated/figures/ExtensionAbility.png deleted file mode 100644 index eeba9d61b27b3a506d18b2e3cc59a7a4f2036841..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/ExtensionAbility.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/aa-dump-a.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-a.PNG deleted file mode 100644 index ae8d41f65f68d73895be5bbbb539c0d220b2a9a5..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/aa-dump-a.PNG and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/aa-dump-i.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-i.PNG deleted file mode 100644 index 12998c5ba3e7d667d1147b6e825f8d110d5c5c5e..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/aa-dump-i.PNG and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/aa-dump-l.PNG b/en/application-dev/ability-deprecated/figures/aa-dump-l.PNG deleted file mode 100644 index a6797eef284990e3fa25e71562ac8afbddf0821d..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/aa-dump-l.PNG and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/contextIntroduction.png b/en/application-dev/ability-deprecated/figures/contextIntroduction.png deleted file mode 100644 index 50ec4d39f722431513051be8f6674f15307117f4..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/contextIntroduction.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/continuation-info.png b/en/application-dev/ability-deprecated/figures/continuation-info.png deleted file mode 100644 index e6335847a8025bf8b9c1ee2bc67dc9ed733f7b5a..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/continuation-info.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/continuationManager.png b/en/application-dev/ability-deprecated/figures/continuationManager.png deleted file mode 100644 index 8447f339a8fc2e911aaf7d3f86557c980eecac44..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/continuationManager.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/fa-dataability-uri.png b/en/application-dev/ability-deprecated/figures/fa-dataability-uri.png deleted file mode 100644 index d89ada0ee9b2f9f655a6c3d8b0df17d6b1ca9326..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/fa-dataability-uri.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/fa-form-example.png b/en/application-dev/ability-deprecated/figures/fa-form-example.png deleted file mode 100644 index 795e96171e6d890e72a09382906302dd0fa45fab..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/fa-form-example.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/fa-pageAbility-lifecycle.png b/en/application-dev/ability-deprecated/figures/fa-pageAbility-lifecycle.png deleted file mode 100644 index 59a06741053c85cab6ea90b41bd16a6f2e1ff508..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/fa-pageAbility-lifecycle.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/fa-threading-model.png b/en/application-dev/ability-deprecated/figures/fa-threading-model.png deleted file mode 100644 index c155caf9a39e95cf7b8128090edb5013d2d956c4..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/fa-threading-model.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/favsstage.png b/en/application-dev/ability-deprecated/figures/favsstage.png deleted file mode 100644 index 4e5980fc1df4634d4ea1ff23158e79d62637f8ba..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/favsstage.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/lifecycle.png b/en/application-dev/ability-deprecated/figures/lifecycle.png deleted file mode 100644 index 345dd474c68069251a2c4ce8c9e8d792dbe029ef..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/lifecycle.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/page-ability-lifecycle.png b/en/application-dev/ability-deprecated/figures/page-ability-lifecycle.png deleted file mode 100644 index b35954967bb9c733725da2f0700481932619ae45..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/page-ability-lifecycle.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/stage-call.png b/en/application-dev/ability-deprecated/figures/stage-call.png deleted file mode 100644 index 4c0c0770a4dce6f275b0fc355f70c5dfca2adb17..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/stage-call.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/stageabilitylifecyclecallback.png b/en/application-dev/ability-deprecated/figures/stageabilitylifecyclecallback.png deleted file mode 100644 index 8dbfac680bc9ce6e0509ebc19bfc0ca035187c90..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/stageabilitylifecyclecallback.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/stageconcept.png b/en/application-dev/ability-deprecated/figures/stageconcept.png deleted file mode 100644 index 5f7c1776ddd207c14b60e9eef22ba22a1c77ad2a..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/stageconcept.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/stagedesign.png b/en/application-dev/ability-deprecated/figures/stagedesign.png deleted file mode 100644 index c901b5196aeb255905b6add4fdfb960e66a4d904..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/stagedesign.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/figures/stageprocessmodel.png b/en/application-dev/ability-deprecated/figures/stageprocessmodel.png deleted file mode 100644 index 18745767786674c496d6a41afe2e8df937745a4d..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/figures/stageprocessmodel.png and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-caution.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-caution.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-caution.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-danger.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-danger.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-danger.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-note.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-note.gif deleted file mode 100644 index 6314297e45c1de184204098efd4814d6dc8b1cda..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-note.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-notice.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-notice.gif deleted file mode 100644 index 86024f61b691400bea99e5b1f506d9d9aef36e27..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-notice.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-tip.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-tip.gif deleted file mode 100644 index 93aa72053b510e456b149f36a0972703ea9999b7..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-tip.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/public_sys-resources/icon-warning.gif b/en/application-dev/ability-deprecated/public_sys-resources/icon-warning.gif deleted file mode 100644 index 6e90d7cfc2193e39e10bb58c38d01a23f045d571..0000000000000000000000000000000000000000 Binary files a/en/application-dev/ability-deprecated/public_sys-resources/icon-warning.gif and /dev/null differ diff --git a/en/application-dev/ability-deprecated/stage-ability-continuation.md b/en/application-dev/ability-deprecated/stage-ability-continuation.md deleted file mode 100644 index 854362d6731bba4edadfbf667d3186013c4b9033..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-ability-continuation.md +++ /dev/null @@ -1,290 +0,0 @@ -# Ability Continuation Development - -## When to Use - -Ability continuation is to continue the current mission of an application, including the UI component state variables and distributed objects, on another device. The UI component state variables are used to synchronize UI data, and the distributed objects are used to synchronize memory data. - -## Available APIs - -The following table lists the APIs used for ability continuation. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). - -**Table 1** Ability continuation APIs - -|API| Description| -|:------ | :------| -| onContinue(wantParam : {[key: string]: any}): OnContinueResult | Called by the initiator to store the data required for continuation. The return value indicates whether the continuation request is accepted. The value **AGREE** means that the continuation request is accepted, **REJECT** means that the continuation request is rejected, and **MISMATCH** means a version mismatch.| -| onCreate(want: Want, param: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the multi-instance ability scenario.| -| onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; | Called by the target to restore the data and UI page in the singleton ability scenario.| - - - -**Figure 1** Ability continuation development - -![continuation_dev](figures/continuation-info.png) - -In effect, ability continuation is a cross-device ability startup that carries data. When a continuation action is initiated, the system on device A calls back **onContinue()** of the application. You must implement storage of the current data in this API. Then, the system initiates a cross-device ability startup on device B and transmits the data to device B. The system on device B calls back **onCreate()** or **onNewWant()**. You must implement restoration of the transmitted data in this API. - -## How to Develop - -The code snippets provided below are all from [Sample](https://gitee.com/openharmony/ability_dmsfwk/tree/master/services/dtbschedmgr/test/samples/continuationManualTestSuite). - -### Application Continuation - -1. Modify the configuration file. - - - Configure the application to support ability continuation. - - Set the **continuable** field in the **module.json5** file to **true**. The default value is **false**. If this parameter is set to **false**, the application cannot be continued on another device. - - ```javascript - { - "module": { - "abilities": [ - { - "continuable": true - } - ] - } - } - ``` - - - - Configure the application startup type. - - If **launchType** is set to **multiton** in the **module.json5** file, the application is of the multi-instance launch type. During ability continuation, regardless of whether the application is already open, the target starts the application and restores the UI page. If **launchType** is set to **singleton**, the application is of the singleton launch type. If the application is already open, the target clears the existing page stack and restores the UI page. For more information, see "Launch Type" in [Ability Development](./stage-ability.md). - - Configure a multi-instance application as follows: - - ```javascript - { - "module": { - "abilities": [ - { - "launchType": "multiton" - } - ] - } - } - ``` - - Configure a singleton application as follows or retain the default settings of **launchType**: - - ```javascript - { - "module": { - "abilities": [ - { - "launchType": "singleton" - } - ] - } - } - ``` - - - Apply for the distributed permissions. - - Declare the **DISTRIBUTED_DATASYNC** permission in the **module.json5** file for the application. - - ```javascript - "requestPermissions": [ - { - "name": "ohos.permission.DISTRIBUTED_DATASYNC" - }, - ``` - - This permission must be granted by the user in a dialog box when the application is started for the first time. To enable the application to display a dialog box to ask for the permission, add the following code to **onWindowStageCreate** of the **Ability** class: - - ```javascript - requestPermissions = async () => { - let permissions: Array = [ - "ohos.permission.DISTRIBUTED_DATASYNC" - ]; - let needGrantPermission = false - let accessManger = accessControl.createAtManager() - Logger.info("app permission get bundle info") - let bundleInfo = await bundle.getApplicationInfo(BUNDLE_NAME, 0, 100) - Logger.info(`app permission query permission ${bundleInfo.accessTokenId.toString()}`) - for (const permission of permissions) { - Logger.info(`app permission query grant status ${permission}`) - try { - let grantStatus = await accessManger.verifyAccessToken(bundleInfo.accessTokenId, permission) - if (grantStatus === PERMISSION_REJECT) { - needGrantPermission = true - break; - } - } catch (err) { - Logger.error(`app permission query grant status error ${permission} ${JSON.stringify(err)}`) - needGrantPermission = true - break; - } - } - if (needGrantPermission) { - Logger.info("app permission needGrantPermission") - try { - await accessManger.requestPermissionsFromUser(this.context, permissions) - } catch (err) { - Logger.error(`app permission ${JSON.stringify(err)}`) - } - } else { - Logger.info("app permission already granted") - } - } - ``` - - - -2. Implement the **onContinue()** API. - - The **onContinue()** API is called by the initiator to save the UI component state variables and memory data and prepare for continuation. After the application completes the continuation preparation, the system must return either **OnContinueResult.AGREE(0)** to accept the continuation request or an error code to reject the request. If this API is not implemented, the system rejects the continuation request by default. - - Modules to import: - - ```javascript - import Ability from '@ohos.application.Ability'; - import AbilityConstant from '@ohos.application.AbilityConstant'; - ``` - - To implement ability continuation, you must implement this API and have the value **AGREE** returned. - - You can obtain the target device ID (identified by the key **targetDevice**) and the version number (identified by the key **version**) of the application installed on the target device from the **wantParam** parameter of this API. The version number can be used for compatibility check. If the current application version is incompatible with that on the target device, **OnContinueResult.MISMATCH** can be returned to reject the continuation request. - - Example: - - ```javascript - onContinue(wantParam : {[key: string]: any}) { - Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) - let workInput = AppStorage.Get('ContinueWork'); - // Set the user input data into wantParam. - wantParam["work"] = workInput // set user input data into want params - Logger.info(`onContinue input = ${wantParam["input"]}`); - return AbilityConstant.OnContinueResult.AGREE - } - ``` - -3. Implement the continuation logic in the **onCreate()** or **onNewWant()** API. - - The **onCreate()** API is called by the target. When the ability is started on the target device, this API is called to instruct the application to synchronize the memory data and UI component state, and triggers page restoration after the synchronization is complete. If the continuation logic is not implemented, the ability will be started in common startup mode and the page cannot be restored. - - The target device determines whether the startup is **LaunchReason.CONTINUATION** based on **launchReason** in **onCreate()**. - - After data restore is complete, call **restoreWindowStage** to trigger page restoration. - - You can also use **want.parameters.version** in the **want** parameter to obtain the application version number of the initiator. - - Example: - - ```javascript - import Ability from '@ohos.application.Ability'; - import distributedObject from '@ohos.data.distributedDataObject'; - - export default class MainAbility extends Ability { - storage : LocalStorag; - - onCreate(want, launchParam) { - Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) - if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { - // Obtain the user data from the want parameter. - let workInput = want.parameters.work - Logger.info(`work input ${workInput}`) - AppStorage.SetOrCreate('ContinueWork', workInput) - - this.storage = new LocalStorage(); - this.context.restoreWindowStage(this.storage); - } - } - } - ``` -For a singleton ability, use **onNewWant()** to achieve the same implementation. - -### Data Continuation - -Use distributed objects. - -Distributed objects allow cross-device data synchronization like local variables. For two devices that form a Super Device, when data in the distributed data object of an application is added, deleted, or modified on a device, the data for the same application is also updated on the other device. Both devices can listen for the data changes and online and offline states of the other. For details, see [Sharing Distributed Data Objects](../database/data-sync-of-distributed-data-object.md). - -In the ability continuation scenario, the distributed data object is used to synchronize the memory data from the local device to the target device. For details, see [Distributed Data Object Development](../database/database-distributedobject-guidelines.md). - -- In **onContinue()**, the initiator saves the data to be migrated to the distributed object, calls the **save()** API to save the data and synchronize the data to the target device, sets the session ID, and sends the session ID to the target device through **wantParam**. - - ```javascript - import Ability from '@ohos.application.Ability'; - import distributedObject from '@ohos.data.distributedDataObject'; - - var g_object = distributedObject.createDistributedObject({data:undefined}); - - export default class MainAbility extends Ability { - sessionId : string; - - onContinue(wantParam : {[key: string]: any}) { - Logger.info(`onContinue version = ${wantParam.version}, targetDevice: ${wantParam.targetDevice}`) - - if (g_object.__sessionId === undefined) { - this.sessionId = distributedObject.genSessionId() - Logger.info(`onContinue generate new sessionId`) - } - else { - this.sessionId = g_object.__sessionId; - } - - wantParam["session"] = this.sessionId - g_object.data = AppStorage.Get('ContinueStudy'); - Logger.info(`onContinue sessionId = ${this.sessionId}, name = ${g_object.data}`) - g_object.setSessionId(this.sessionId); - g_object.save(wantParam.targetDevice, (result, data)=>{ - Logger.info("save callback"); - Logger.info("save sessionId " + data.sessionId); - Logger.info("save version " + data.version); - Logger.info("save deviceId " + data.deviceId); - }); - ``` - -- The target device obtains the session ID from **onCreate()**, creates a distributed object, and associates the distributed object with the session ID. In this way, the distributed object can be synchronized. Before calling **restoreWindowStage**, ensure that all distributed objects required for continuation have been associated. - - ```javascript - import Ability from '@ohos.application.Ability'; - import distributedObject from '@ohos.data.distributedDataObject'; - - var g_object = distributedObject.createDistributedObject({data:undefined}); - - export default class MainAbility extends Ability { - storage : LocalStorag; - - - onCreate(want, launchParam) { - Logger.info(`MainAbility onCreate ${AbilityConstant.LaunchReason.CONTINUATION}`) - if (launchParam.launchReason == AbilityConstant.LaunchReason.CONTINUATION) { - // Obtain the session ID of the distributed data object from the want parameter. - this.sessionId = want.parameters.session - Logger.info(`onCreate for continuation sessionId: ${this.sessionId}`) - - // Before fetching data from the remote device, reset g_object.data to undefined. - g_object.data = undefined; - // Set the session ID, so the target will fetch data from the remote device. - g_object.setSessionId(this.sessionId); - - AppStorage.SetOrCreate('ContinueStudy', g_object.data) - this.storage = new LocalStorage(); - this.context.restoreWindowStage(this.storage); - } - - } - } - ``` - -### More Information - -1. Timeout - - - If the application to be continued is not installed on the target device, the system checks whether the application can be installed on it and waits for a response for 4 seconds. If no response is received within 4 seconds, the caller receives a timeout error code, which means that the application cannot be installed on the target device. If the application can be installed, the system prompts the consumer to install the application on the target device. The consumer can initiate the continuation again after the installation. - - If the application to be continued has been installed on the target device, the system waits for a response to the continuation request for 20 seconds. If no response is received within 20 seconds, the caller receives a timeout error code, which means that the continuation fails. - -2. By default, the system supports page stack information migration, which means that the page stack of the initiator will be automatically migrated to the target device. No adaptation is required. - -### Restrictions - -1. The continuation must be performed between the same ability, which means the same bundle name, module name, and ability name. For details, see [Application Package Structure Configuration File](../quick-start/module-configuration-file.md). -2. Currently, the application can only implement the continuation capability. The continuation action must be initiated by the system. - -### Best Practice - -For better user experience, you are advised to use the **wantParam** parameter to transmit data smaller than 100 KB and use distributed objects to transmit data larger than 100 KB. diff --git a/en/application-dev/ability-deprecated/stage-ability.md b/en/application-dev/ability-deprecated/stage-ability.md deleted file mode 100644 index 4ee2ac9dc8ef07ec4ff7020156e9536d6b5b980b..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-ability.md +++ /dev/null @@ -1,303 +0,0 @@ -# Ability Development -## When to Use -Ability development in the [stage model](stage-brief.md) is significantly different from that in the FA model. The stage model requires you to declare the application package structure in the **module.json5** and **app.json5** files during application development. For details about the configuration file, see [Application Package Structure Configuration File](../quick-start/application-package-structure-stage.md). To develop an ability based on the stage model, implement the following logic: -- Create an ability that supports screen viewing and human-machine interaction. You must implement the following scenarios: ability lifecycle callbacks, obtaining ability configuration, requesting permissions, and notifying environment changes. -- Start an ability. You need to implement ability startup on the same device, on a remote device, or with a specified UI page. -- Call abilities. For details, see [Call Development](stage-call.md). -- Connect to and disconnect from a Service Extension ability. For details, see [Service Extension Ability Development](stage-serviceextension.md). -- Continue the ability on another device. For details, see [Ability Continuation Development](stage-ability-continuation.md). - -### Launch Type -An ability can be launched in the **standard**, **singleton**, or **specified** mode, as configured by **launchType** in the **module.json5** file. Depending on the launch type, the action performed when the ability is started differs, as described below. - -| Launch Type | Description |Action | -| ----------- | ------- |---------------- | -| multiton | Multi-instance mode| A new instance is started each time an ability starts.| -| singleton | Singleton mode | The ability has only one instance in the system. If an instance already exists when an ability is started, that instance is reused.| -| specified | Instance-specific| The internal service of an ability determines whether to create multiple instances during running.| - -By default, the singleton mode is used. The following is an example of the **module.json5** file: -```json -{ - "module": { - "abilities": [ - { - "launchType": "singleton", - } - ] - } -} -``` -## Creating an Ability -### Available APIs -The table below describes the APIs provided by the **AbilityStage** class, which has the **context** attribute. For details about the APIs, see [AbilityStage](../reference/apis/js-apis-app-ability-abilityStage.md). - -**Table 1** AbilityStage APIs -|API|Description| -|:------|:------| -|onCreate(): void|Called when an ability stage is created.| -|onAcceptWant(want: Want): string|Called when a specified ability is started.| -|onConfigurationUpdated(config: Configuration): void|Called when the global configuration is updated.| - -The table below describes the APIs provided by the **Ability** class. For details about the APIs, see [Ability](../reference/apis/js-apis-application-ability.md). - -**Table 2** Ability APIs - -|API|Description| -|:------|:------| -|onCreate(want: Want, param: AbilityConstant.LaunchParam): void|Called when an ability is created.| -|onDestroy(): void|Called when the ability is destroyed.| -|onWindowStageCreate(windowStage: window.WindowStage): void|Called when a **WindowStage** is created for the ability. You can use the **window.WindowStage** APIs to implement operations such as page loading.| -|onWindowStageDestroy(): void|Called when the **WindowStage** is destroyed for the ability.| -|onForeground(): void|Called when the ability is switched to the foreground.| -|onBackground(): void|Called when the ability is switched to the background.| -|onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void|Called when the ability launch type is set to **singleton**.| -|onConfigurationUpdated(config: Configuration): void|Called when the configuration of the environment where the ability is running is updated.| -### Implementing AbilityStage and Ability Lifecycle Callbacks -To create Page abilities for an application in the stage model, you must implement the **AbilityStage** class and ability lifecycle callbacks, and use the **Window** class to set the pages. The sample code is as follows: -1. Import the **AbilityStage** module. - ``` - import AbilityStage from "@ohos.application.AbilityStage" - ``` -2. Implement the **AbilityStage** class. The default relative path generated by the APIs is **entry\src\main\ets\Application\AbilityStage.ts**. - ```ts - export default class MyAbilityStage extends AbilityStage { - onCreate() { - console.log("MyAbilityStage onCreate") - } - } - ``` -3. Import the **Ability** module. - ```js - import Ability from '@ohos.application.Ability' - ``` -4. Implement the lifecycle callbacks of the **UIAbility** class. The default relative path generated by the APIs is **entry\src\main\ets\entryability\EntryAbility.ts**. - - In the **onWindowStageCreate(windowStage)** API, use **loadContent** to set the application page to be loaded. For details about how to use the **Window** APIs, see [Window Development](../windowmanager/application-window-stage.md). - ```ts - export default class MainAbility extends Ability { - onCreate(want, launchParam) { - console.log("MainAbility onCreate") - } - - onDestroy() { - console.log("MainAbility onDestroy") - } - - onWindowStageCreate(windowStage) { - console.log("MainAbility onWindowStageCreate") - - windowStage.loadContent("pages/index").then(() => { - console.log("MainAbility load content succeed") - }).catch((error) => { - console.error("MainAbility load content failed with error: " + JSON.stringify(error)) - }) - } - - onWindowStageDestroy() { - console.log("MainAbility onWindowStageDestroy") - } - - onForeground() { - console.log("MainAbility onForeground") - } - - onBackground() { - console.log("MainAbility onBackground") - } - } - ``` -### Obtaining AbilityStage and Ability Configurations -Both the **AbilityStage** and **Ability** classes have the **context** attribute. An application can obtain the context of an **Ability** instance through **this.context** to obtain the configuration details. - -The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **AbilityStage** class. The sample code is as follows: - -```ts -import AbilityStage from "@ohos.application.AbilityStage" - -export default class MyAbilityStage extends AbilityStage { - onCreate() { - console.log("MyAbilityStage onCreate") - let context = this.context - console.log("MyAbilityStage bundleCodeDir" + context.bundleCodeDir) - - let currentHapModuleInfo = context.currentHapModuleInfo - console.log("MyAbilityStage hap module name" + currentHapModuleInfo.name) - console.log("MyAbilityStage hap module mainAbilityName" + currentHapModuleInfo.mainAbilityName) - - let config = this.context.config - console.log("MyAbilityStage config language" + config.language) - } -} -``` - -The following example shows how an application obtains the bundle code directory, HAP file name, ability name, and system language through the **context** attribute in the **Ability** class. The sample code is as follows: -```ts -import Ability from '@ohos.application.Ability' -export default class MainAbility extends Ability { - onCreate(want, launchParam) { - console.log("MainAbility onCreate") - let context = this.context - console.log("MainAbility bundleCodeDir" + context.bundleCodeDir) - - let abilityInfo = this.context.abilityInfo; - console.log("MainAbility ability bundleName" + abilityInfo.bundleName) - console.log("MainAbility ability name" + abilityInfo.name) - - let config = this.context.config - console.log("MainAbility config language" + config.language) - } -} -``` -### Notifying of Environment Changes -Environment changes include changes of global configurations and ability configurations. Currently, the global configurations include the system language and color mode. The change of global configurations is generally triggered by configuration items in **Settings** or icons in **Control Panel**. The ability configuration is specific to a single **Ability** instance, including the display ID, screen resolution, and screen orientation. The configuration is related to the display where the ability is located, and the change is generally triggered by the window. Before configuring a project, define the project in the [Configuration](../reference/apis/js-apis-application-configuration.md) class. - -For an application in the stage model, when the configuration changes, its abilities are not restarted, but the **onConfigurationUpdated(config: Configuration)** callback is triggered. If the application needs to perform processing based on the change, you can override **onConfigurationUpdated**. Note that the **Configuration** object in the callback contains all the configurations of the current ability, not only the changed configurations. - -The following example shows the implementation of the **onConfigurationUpdated** callback in the **AbilityStage** class. The callback is triggered when the system language and color mode are changed. -```ts -import AbilityStage from '@ohos.application.AbilityStage' -import ConfigurationConstant from '@ohos.application.ConfigurationConstant' - -export default class MyAbilityStage extends AbilityStage { - onConfigurationUpdated(config) { - if (config.colorMode === ConfigurationConstant.ColorMode.COLOR_MODE_DARK) { - console.log('colorMode changed to dark') - } - } -} -``` - -The following example shows the implementation of the **onConfigurationUpdated** callback in the **Ability** class. The callback is triggered when the system language, color mode, or display parameters (such as the direction and density) change. -```ts -import Ability from '@ohos.application.Ability' -import ConfigurationConstant from '@ohos.application.ConfigurationConstant' - -export default class MainAbility extends Ability { - direction : number; - - onCreate(want, launchParam) { - this.direction = this.context.config.direction - } - - onConfigurationUpdated(config) { - if (this.direction !== config.direction) { - console.log(`direction changed to ${config.direction}`) - } - } -} -``` -## Starting an Ability -### Available APIs -The **Ability** class has the **context** attribute, which belongs to the **AbilityContext** class. The **AbilityContext** class has the **abilityInfo**, **currentHapModuleInfo**, and other attributes as well as the APIs used for starting abilities. For details, see [AbilityContext](../reference/apis/js-apis-inner-application-applicationContext.md). - -**Table 3** AbilityContext APIs -|API|Description| -|:------|:------| -|startAbility(want: Want, callback: AsyncCallback\): void|Starts an ability.| -|startAbility(want: Want, options?: StartOptions): Promise\|Starts an ability.| -|startAbilityWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the account ID.| -|startAbilityWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the account ID.| -|startAbilityForResult(want: Want, callback: AsyncCallback\): void|Starts an ability with the returned result.| -|startAbilityForResult(want: Want, options?: StartOptions): Promise\|Starts an ability with the returned result.| -|startAbilityForResultWithAccount(want: Want, accountId: number, callback: AsyncCallback\): void|Starts an ability with the execution result and account ID.| -|startAbilityForResultWithAccount(want: Want, accountId: number, options?: StartOptions): Promise\|Starts an ability with the execution result and account ID.| -### Starting an Ability on the Same Device -An application can obtain the context of an **Ability** instance through **this.context** and then use the **startAbility** API in the **AbilityContext** class to start the ability. The ability can be started by specifying **Want**, **StartOptions**, and **accountId**, and the operation result can be returned using a callback or **Promise** instance. The sample code is as follows: -```ts -let context = this.context -var want = { - "deviceId": "", - "bundleName": "com.example.MyApplication", - "abilityName": "MainAbility" -}; -context.startAbility(want).then(() => { - console.log("Succeed to start ability") -}).catch((error) => { - console.error("Failed to start ability with error: "+ JSON.stringify(error)) -}) -``` - -### Starting an Ability on a Remote Device ->This feature applies only to system applications, since the **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. -In the cross-device scenario, you must specify the ID of the remote device. The sample code is as follows: -```ts -let context = this.context -var want = { - "deviceId": getRemoteDeviceId(), - "bundleName": "com.example.MyApplication", - "abilityName": "MainAbility" -}; -context.startAbility(want).then(() => { - console.log("Succeed to start remote ability") -}).catch((error) => { - console.error("Failed to start remote ability with error: " + JSON.stringify(error)) -}) -``` -Obtain the ID of a specified device from **DeviceManager**. The sample code is as follows: -```ts -import deviceManager from '@ohos.distributedHardware.deviceManager'; -function getRemoteDeviceId() { - if (typeof dmClass === 'object' && dmClass != null) { - var list = dmClass.getTrustedDeviceListSync(); - if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { - console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null"); - return; - } - console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId); - return list[0].deviceId; - } else { - console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null"); - } -} -``` -Request the permission **ohos.permission.DISTRIBUTED_DATASYNC** from consumers. This permission is used for data synchronization. For details about the sample code for requesting permissions, see [abilityAccessCtrl.requestPermissionsFromUse](../reference/apis/js-apis-abilityAccessCtrl.md#requestpermissionsfromuser9). -### Starting an Ability with the Specified Page -If the launch type of an ability is set to **singleton** and the ability has been started, the **onNewWant** callback is triggered when the ability is started again. You can pass start options through the **want**. For example, to start an ability with the specified page, use the **uri** or **parameters** parameter in the **want** to pass the page information. Currently, the ability in the stage model cannot directly use the **router** capability. You must pass the start options to the custom component and invoke the **router** method to display the specified page during the custom component lifecycle management. The sample code is as follows: - -When using **startAbility** to start an ability again, use the **uri** parameter in the **want** to pass the page information. -```ts -async function reStartAbility() { - try { - await this.context.startAbility({ - bundleName: "com.sample.MyApplication", - abilityName: "MainAbility", - uri: "pages/second" - }) - console.log('start ability succeed') - } catch (error) { - console.error(`start ability failed with ${error.code}`) - } -} -``` - -Obtain the **want** parameter that contains the page information from the **onNewWant** callback of the ability. -```ts -import Ability from '@ohos.application.Ability' - -export default class MainAbility extends Ability { - onNewWant(want, launchParams) { - globalThis.newWant = want - } -} -``` - -Obtain the **want** parameter that contains the page information from the custom component and process the route based on the URI. -```ts -import router from '@ohos.router' - -@Entry -@Component -struct Index { - newWant = undefined - - onPageShow() { - console.info('Index onPageShow') - let newWant = globalThis.newWant - if (newWant.hasOwnProperty("uri")) { - router.push({ url: newWant.uri }); - globalThis.newWant = undefined - } - } -} -``` diff --git a/en/application-dev/ability-deprecated/stage-brief.md b/en/application-dev/ability-deprecated/stage-brief.md deleted file mode 100644 index 190644c2c0d7e114d0e898de1a8837695bdf049e..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-brief.md +++ /dev/null @@ -1,114 +0,0 @@ -# Stage Model Overview - -## Design Ideas - -The stage model is designed to provide a better application development mode in the distributed environment. - -The following figure shows the design ideas of the stage model. - -![stagedesign](figures/stagedesign.png) - -The stage model is designed based on the following considerations: - -- Efficient management of application processes - -As the device memory becomes larger, the number of processes concurrently running in the system increases. If the number of concurrent processes reaches several hundreds, the overall power consumption and performance of the system will be adversely affected without effective management measures. To restrict the behavior of background processes, the stage model uses four measures: transient task, continuous task, agent task, and Work Scheduler task. With these measures, foreground processes will obtain guaranteed resources, thereby delivering a better user experience. - -- Native support for cross-device migration and multi-device collaboration - -OpenHarmony is a native distributed OS. Its application framework must be designed for easier component migration and collaboration across devices. The stage model achieves this design objective by providing features such as separation between ability and UI as well as integration of UI display and service capabilities. - -- Different window forms for various device types - -The stage model redefines the ability lifecycle. In terms of architecture, the component manager and window manager are decoupled. This facilitates adaptation between window forms and device types. - -## Basic Concepts - -The following figure shows the basic concepts in the stage model. - -![stageconcept](figures/stageconcept.png) - -- **HAP**: basic unit for building, distributing, and loading OpenHarmony applications. Each HAP corresponds to a module in the development state. In an application, **moduleName** uniquely identifies a module. -- **Bundle**: an OpenHarmony application identified by **appid**. A bundle can contain multiple HAP files. Each application has a **bundleName**. However, **bundleName** must be used together with **appid** and other information to uniquely identify an application. -- **AbilityStage**: runtime object of an HAP. It is created when the HAP is loaded to the process for the first time and is visible to developers in the runtime. -- **Application**: runtime object of a bundle. It is invisible to developers in the runtime. -- **Context**: base class that provides APIs in the runtime to obtain information such as the bundle name, module name, and path. The **Context** classes of the Ability and ExtensionAbility components inherit from this class. -- **Ability**: provides lifecycle callbacks, holds the ability context, and supports cross-device component migration and multi-device collaboration. -- **ExtensionAbility**: general name of scenario-based Extension abilities. The system defines multiple scenario-based **ExtensionAbility** classes, each of which has its own **ExtensionContext**. -- **WindowStage**: local window manager. -- **Window**: application window, which holds an ArkUI engine instance. -- **ArkUI Page**: UI developed based on ArkUI. - - -## Lifecycle - -The ability and ability stage are key objects in the application lifecycle. - -For details about the lifecycle differences between the stage model and FA model, see [Ability Framework Overview](ability-brief.md). This section focuses on the ability lifecycle transition and the scheduling relationships between the ability, ability stage, and window stage. - -![stageabilitylifecyclecallback](figures/stageabilitylifecyclecallback.png) - -To implement device adaptation and multi-window scalability, OpenHarmony decouples the component manager from the window manager. - -The ability lifecycle defined in the stage model includes only the creation, destruction, foreground, and background states. The gain focus and lose focus states that are closely related to UI are defined in the window stage. This implements weak coupling between the abilities and windows. On the service side, the window manager notifies the component manager of the foreground and background state changes, so the component manager only senses the foreground and background state changes but not the focus changes. - -There are two lifecycle states related to the window stage in **Ability**: **onWindowStageCreate** and **onWindowStageDestroy**. They are valid only for devices with the display capability. **onWindowStageCreate** is invoked when a window stage is created, where you can call **loadContent** to set pages to be loaded for the ability. **onWindowStageDestroy** is invoked when the window stage is destroyed, where you can release resources. - - -## Ability Instances and Missions - -Abilities can be started in any of the following modes: - -* **Singleton**: For each type of ability, only one instance exists in the application process. **Ability1** in the figure below is started in singleton mode. -* **Standard**: Each time **startAbility** is called, an instance of the specified ability type is created in the application process. **Ability2** in the figure below is started in standard mode. -* **Specified**: Before creating an **Ability** instance, you can create a key for the instance. Each time **startAbility** is called, the system asks the application which ability instance (corresponding to a key) will be used. **Ability3** in the figure below is started in specified mode. - -Each **Ability** instance corresponds to a mission in **Recents**. - -The mission corresponding to an ability instance has a snapshot of the ability instance. After the ability instance is destroyed, the ability class information and snapshot are retained in the mission until the user deletes the information or the storage space reaches the upper limit. - - ![AbilityComponentInstanceMission](figures/AbilityComponentInstanceMission.png) - -## ExtensionAbility Mechanism - -Different from the ability used for UI display, ExtensionAbility provides a restricted running environment. - -ExtensionAbility has the following features: - -- Its process runs independently from the main process but shares the same storage sandbox with the main process. There is no inter-process communication (IPC) between the ExtensionAbility process and the main process. - -- It has an independent context that provides scenario-specific APIs. - -- It is created by the system, rather than by applications. - -- The lifecycles of the ExtensionAbility component and process are managed by the system. - -The following figure uses the widget an example. **FormExtensionAbility** is the base class. You can inherit from this class to provide widget information. The lifecycle of the **FormExtensionAbility** instance and that of the ExtensionAbility process where the instance is located are managed by a system service named **FormManagerService**. - -![ExtensionAbility](figures/ExtensionAbility.png) - -## Process Model - -OpenHarmony forces strong control policies on application processes. No APIs are provided to configure multiple processes. All application processes are created and managed by the system. - -The processes of an application can be classified into three types: - -- Main process: runs the **UIAbility** component, UI, and service logic. - -- Extension process: runs classes derived from **ExtensionAbility** in the application. The lifecycle of this process is managed by a scenario-specific system service. - -- Render process: created for the WebView and used to load the WebView rendering library. - - The following figure shows the process model of an application. - - ![stageprocessmodel](figures/stageprocessmodel.png) - - - -## Application Package Structure - -For details about the project directory structure of the stage model, see [OpenHarmony Project Overview](https://developer.harmonyos.com/en/docs/documentation/doc-guides/ohos-project-overview-0000001218440650#section56487581904). - -For details about how to configure the application package structure of the stage model, see [Application Package Structure Configuration File](../quick-start/application-configuration-file-overview-stage.md). - - diff --git a/en/application-dev/ability-deprecated/stage-call.md b/en/application-dev/ability-deprecated/stage-call.md deleted file mode 100644 index 91388980580d8ca22188ead3e58288bf9da658af..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-call.md +++ /dev/null @@ -1,309 +0,0 @@ -# Ability Call Development -## When to Use -Ability call is an extension of the ability capability. It enables an ability to be invoked by and communicate with external systems. The ability invoked can be either started in the foreground or created and run in the background. You can use the ability call to implement data sharing between two abilities (caller ability and callee ability) through inter-process communication (IPC). - -The core API used for the ability call is **startAbilityByCall**, which differs from **startAbility** in the following ways: - - **startAbilityByCall** supports ability startup in the foreground and background, whereas **startAbility** supports ability startup in the foreground only. - - The caller ability can use the **Caller** object returned by **startAbilityByCall** to communicate with the callee ability, but **startAbility** does not provide the communication capability. - -Ability call is usually used in the following scenarios: -- Communicating with the callee ability -- Starting the callee ability in the background - -**Table 1** Terms used in the ability call -|Term|Description| -|:------|:------| -|Caller ability|Ability that triggers the ability call.| -|Callee ability|Ability invoked by the ability call.| -|Caller |Object returned by **startAbilityByCall** and used by the caller ability to communicate with the callee ability.| -|Callee |Object held by the callee ability to communicate with the caller ability.| -|IPC |Inter-process communication.| - -The ability call process is as follows: - - The caller ability uses **startAbilityByCall** to obtain a **Caller** object and uses **call()** of the **Caller** object to send data to the callee ability. - - The callee ability, which holds a **Callee** object, uses **on()** of the **Callee** object to register a callback. This callback is invoked when the callee ability receives data from the caller ability. -![stage-call](figures/stage-call.png) - -> **NOTE** -> -> The launch type of the callee ability must be **singleton**. -> -> Currently, only system applications can use the ability call. - -## Available APIs -The table below describes the ability call APIs. For details, see [Ability](../reference/apis/js-apis-application-ability.md#caller). - -**Table 2** Ability call APIs -|API|Description| -|:------|:------| -|startAbilityByCall(want: Want): Promise\|Starts an ability in the foreground (through the **want** configuration) or background (default) and obtains the **Caller** object for communication with the ability. For details, see [AbilityContext](../reference/apis/js-apis-ability-context.md#abilitycontextstartabilitybycall) or **ServiceExtensionContext**.| -|on(method: string, callback: CalleeCallBack): void|Callback invoked when the callee ability registers a method.| -|off(method: string): void|Callback invoked when the callee ability deregisters a method.| -|call(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability.| -|callWithResult(method: string, data: rpc.Sequenceable): Promise\|Sends agreed sequenceable data to the callee ability and obtains the agreed sequenceable data returned by the callee ability.| -|release(): void|Releases the **Caller** object.| -|on(type: "release", callback: OnReleaseCallback): void|Callback invoked when the **Caller** object is released.| - -## How to Develop -The procedure for developing the ability call is as follows: -1. Create a callee ability. -2. Access the callee ability. - -### Creating a Callee Ability -For the callee ability, implement the callback to receive data and the methods to marshal and unmarshal data. When data needs to be received, use **on()** to register a listener. When data does not need to be received, use **off()** to deregister the listener. - -1. **Configure the ability launch type.** - - Set **launchType** of the callee ability to **singleton** in the **module.json5** file. - - |JSON Field|Description| - |:------|:------| - |"launchType"|Ability launch type. Set this parameter to **singleton**.| - - An example of the ability configuration is as follows: - - ```json - "abilities":[{ - "name": ".CalleeAbility", - "srcEnty": "./ets/CalleeAbility/CalleeAbility.ts", - "launchType": "singleton", - "description": "$string:CalleeAbility_desc", - "icon": "$media:icon", - "label": "$string:CalleeAbility_label", - "exported": true - }] - ``` - -2. **Import the ability module.** - - ```ts - import Ability from '@ohos.app.ability.UIAbility'; - ``` - -3. **Define the agreed sequenceable data.** - - The data formats sent and received by the caller and callee abilities must be consistent. In the following example, the data formats are number and string. The code snippet is as follows: - - ```ts - export default class MySequenceable { - num: number = 0 - str: string = "" - - constructor(num, string) { - this.num = num - this.str = string - } - - marshalling(messageParcel) { - messageParcel.writeInt(this.num) - messageParcel.writeString(this.str) - return true - } - - unmarshalling(messageParcel) { - this.num = messageParcel.readInt() - this.str = messageParcel.readString() - return true - } - } - ``` - -4. **Implement Callee.on and Callee.off.** - - The time to register a listener for the callee ability depends on your application. The data sent and received before the listener is registered and that after the listener is deregistered are not processed. In the following example, the **MSG_SEND_METHOD** listener is registered in **onCreate** of the ability and deregistered in **onDestroy**. After receiving sequenceable data, the application processes the data and returns the data result. You need to implement processing based on service requirements. The code snippet is as follows: - - ```ts - const TAG: string = '[CalleeAbility]' - const MSG_SEND_METHOD: string = 'CallSendMsg' - - function sendMsgCallback(data) { - console.log('CalleeSortFunc called') - - // Obtain the sequenceable data sent by the caller ability. - let receivedData = new MySequenceable(0, '') - data.readSequenceable(receivedData) - console.log(`receiveData[${receivedData.num}, ${receivedData.str}]`) - - // Process the data. - // Return the sequenceable data result to the caller ability. - return new MySequenceable(receivedData.num + 1, `send ${receivedData.str} succeed`) - } - - export default class CalleeAbility extends Ability { - onCreate(want, launchParam) { - try { - this.callee.on(MSG_SEND_METHOD, sendMsgCallback) - } catch (error) { - console.log(`${MSG_SEND_METHOD} register failed with error ${JSON.stringify(error)}`) - } - } - - onDestroy() { - try { - this.callee.off(MSG_SEND_METHOD) - } catch (error) { - console.error(TAG, `${MSG_SEND_METHOD} unregister failed with error ${JSON.stringify(error)}`) - } - } - } - ``` - -### Accessing the Callee Ability -1. **Import the Ability module.** - - ```ts - import Ability from '@ohos.app.ability.UIAbility'; - ``` - -2. **Obtain the Caller object.** - - The **context** attribute of the ability implements **startAbilityByCall** to obtain the **Caller** object for communication. The following example uses **this.context** to obtain the **context** attribute of the ability, uses **startAbilityByCall** to start the callee ability, obtain the **Caller** object, and register the **onRelease** listener of the caller ability. You need to implement processing based on service requirements. The code snippet is as follows: - - ```ts - // Register the onRelease listener of the caller ability. - private regOnRelease(caller) { - try { - caller.on("release", (msg) => { - console.log(`caller onRelease is called ${msg}`) - }) - console.log('caller register OnRelease succeed') - } catch (error) { - console.log(`caller register OnRelease failed with ${error}`) - } - } - - async onButtonGetCaller() { - try { - this.caller = await context.startAbilityByCall({ - bundleName: 'com.samples.CallApplication', - abilityName: 'CalleeAbility' - }) - if (this.caller === undefined) { - console.log('get caller failed') - return - } - console.log('get caller success') - this.regOnRelease(this.caller) - } catch (error) { - console.log(`get caller failed with ${error}`) - } - } - ``` - - In the cross-device scenario, you need to specify the ID of the peer device. The code snippet is as follows: - - ```ts - async onButtonGetRemoteCaller() { - var caller = undefined - var context = this.context - - context.startAbilityByCall({ - deviceId: getRemoteDeviceId(), - bundleName: 'com.samples.CallApplication', - abilityName: 'CalleeAbility' - }).then((data) => { - if (data != null) { - caller = data - console.log('get remote caller success') - // Register the onRelease listener of the caller ability. - caller.on("release", (msg) => { - console.log(`remote caller onRelease is called ${msg}`) - }) - console.log('remote caller register OnRelease succeed') - } - }).catch((error) => { - console.error(`get remote caller failed with ${error}`) - }) - } - ``` - - Obtain the ID of the peer device from **DeviceManager**. Note that the **getTrustedDeviceListSync** API is open only to system applications. The code snippet is as follows: - - ```ts - import deviceManager from '@ohos.distributedHardware.deviceManager'; - var dmClass; - function getRemoteDeviceId() { - if (typeof dmClass === 'object' && dmClass != null) { - var list = dmClass.getTrustedDeviceListSync() - if (typeof (list) == 'undefined' || typeof (list.length) == 'undefined') { - console.log("MainAbility onButtonClick getRemoteDeviceId err: list is null") - return - } - console.log("MainAbility onButtonClick getRemoteDeviceId success:" + list[0].deviceId) - return list[0].deviceId - } else { - console.log("MainAbility onButtonClick getRemoteDeviceId err: dmClass is null") - } - } - ``` - - In the cross-device scenario, your application must also apply for the data synchronization permission from end users. The code snippet is as follows: - - ```ts - import abilityAccessCtrl from '@ohos.abilityAccessCtrl.d.ts'; - - requestPermission() { - let context = this.context - let permissions: Array = ['ohos.permission.DISTRIBUTED_DATASYNC'] - let atManager = abilityAccessCtrl.createAtManager(); - atManager.requestPermissionsFromUser(context, permissions).then((data) => { - console.log("Succeed to request permission from user with data: "+ JSON.stringify(data)) - }).catch((error) => { - console.log("Failed to request permission from user with error: "+ JSON.stringify(error)) - }) - } - ``` - -3. **Send agreed sequenceable data.** - - The sequenceable data can be sent to the callee ability with or without a return value. The method and sequenceable data must be consistent with those of the callee ability. The following example describes how to send data to the callee ability. The code snippet is as follows: - - ```ts - const MSG_SEND_METHOD: string = 'CallSendMsg' - async onButtonCall() { - try { - let msg = new MySequenceable(1, 'origin_Msg') - await this.caller.call(MSG_SEND_METHOD, msg) - } catch (error) { - console.log(`caller call failed with ${error}`) - } - } - ``` - - In the following, **CallWithResult** is used to send data **originMsg** to the callee ability and assign the data processed by the **CallSendMsg** method to **backMsg**. The code snippet is as follows: - - ```ts - const MSG_SEND_METHOD: string = 'CallSendMsg' - originMsg: string = '' - backMsg: string = '' - async onButtonCallWithResult(originMsg, backMsg) { - try { - let msg = new MySequenceable(1, originMsg) - const data = await this.caller.callWithResult(MSG_SEND_METHOD, msg) - console.log('caller callWithResult succeed') - - let result = new MySequenceable(0, '') - data.readSequenceable(result) - backMsg(result.str) - console.log(`caller result is [${result.num}, ${result.str}]`) - } catch (error) { - console.log(`caller callWithResult failed with ${error}`) - } - } - ``` - -4. **Release the Caller object.** - - When the **Caller** object is no longer required, use **release()** to release it. The code snippet is as follows: - - ```ts - releaseCall() { - try { - this.caller.release() - this.caller = undefined - console.log('caller release succeed') - } catch (error) { - console.log(`caller release failed with ${error}`) - } - } - ``` \ No newline at end of file diff --git a/en/application-dev/ability-deprecated/stage-formextension.md b/en/application-dev/ability-deprecated/stage-formextension.md deleted file mode 100644 index d7abb35881e99620daa888b6e4a97bd8697b2521..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-formextension.md +++ /dev/null @@ -1,415 +0,0 @@ -# Stage Widget Development - -## Widget Overview - -A widget is a set of UI components that display important information or operations specific to an application. It provides users with direct access to a desired application service, without the need to open the application first. - -A widget usually appears as a part of the UI of another application (which currently can only be a system application) and provides basic interactive features such as opening a UI page or sending a message. - -Before you get started, it would be helpful if you have a basic understanding of the following concepts: - -- Widget provider: an atomic service that provides the widget content to display and controls how widget components are laid out and how they interact with users. -- Widget host: an application that displays the widget content and controls the widget location. -- Widget Manager: a resident agent that provides widget management features such as periodic widget updates. - -> **NOTE** -> -> The widget host and provider do not need to be running all the time. The Widget Manager will start the widget provider to obtain widget information when a widget is added, deleted, or updated. - -You only need to develop the widget provider. The system automatically handles the work of the widget host and Widget Manager. - -The widget provider controls the widget content to display, the layout of components used in the widget, and click events bound to the components. - -## When to Use - -Carry out the following operations to develop the widget provider based on the [stage model](stage-brief.md): - -1. Implement lifecycle callbacks by using the **FormExtension** APIs. -2. Create a **FormBindingData** instance. -3. Update a widget by using the **FormProvider** APIs. -4. Develop the widget UI page. - -## Available APIs - -The **FormExtension** class has the following APIs. For details, see [FormExtension](../reference/apis/js-apis-app-form-formExtensionAbility.md). - -**Table 1** FormExtension APIs - -| API | Description | -| :----------------------------------------------------------- | :------------------------------------------- | -| onCreate(want: Want): formBindingData.FormBindingData | Called to notify the widget provider that a widget has been created. | -| onCastToNormal(formId: string): void | Called to notify the widget provider that a temporary widget has been converted to a normal one.| -| onUpdate(formId: string): void | Called to notify the widget provider that a widget has been updated. | -| onVisibilityChange(newStatus: { [key: string]: number }): void | Called to notify the widget provider of the change in widget visibility. | -| onEvent(formId: string, message: string): void | Called to instruct the widget provider to receive and process a widget event. | -| onDestroy(formId: string): void | Called to notify the widget provider that a widget has been destroyed. | -| onConfigurationUpdated(config: Configuration): void; | Called when the configuration of the environment where the widget is running is updated. | - -The **FormExtension** class also has a member context, that is, the **FormExtensionContext** class. For details, see [FormExtensionContext](../reference/apis/js-apis-inner-application-formExtensionContext.md). - -**Table 2** FormExtensionContext APIs - -| API | Description | -| :----------------------------------------------------------- | :----------------------------------------------------------- | -| startAbility(want: Want, callback: AsyncCallback<void>): void | Starts an ability. This API uses an asynchronous callback to return the result. (This is a system API and cannot be called by third-party applications.)| -| startAbility(want: Want): Promise<void> | Starts an ability. This API uses a promise to return the result. (This is a system API and cannot be called by third-party applications.)| - -The table below describes the **FormProvider** APIs. For details, see [FormProvider](../reference/apis/js-apis-application-formProvider.md). - -**Table 3** FormProvider APIs - -| API | Description | -| :----------------------------------------------------------- | :------------------------------------------------ | -| setFormNextRefreshTime(formId: string, minute: number, callback: AsyncCallback<void>): void; | Sets the next refresh time for a widget. This API uses an asynchronous callback to return the result. | -| setFormNextRefreshTime(formId: string, minute: number): Promise<void>; | Sets the next refresh time for a widget. This API uses a promise to return the result.| -| updateForm(formId: string, formBindingData: FormBindingData, callback: AsyncCallback<void>): void; | Updates a widget. This API uses an asynchronous callback to return the result. | -| updateForm(formId: string, formBindingData: FormBindingData): Promise<void>; | Updates a widget. This API uses a promise to return the result. | - -## How to Develop - -### Creating a FormExtension Instance - -To create a widget in the stage model, you need to implement lifecycle callbacks using the **FormExtension** APIs. The code snippet is as follows: - -1. Import the required modules. - - ```javascript - import FormExtension from '@ohos.application.FormExtension' - import formBindingData from '@ohos.application.formBindingData' - import formInfo from '@ohos.application.formInfo' - import formProvider from '@ohos.application.formProvider' - ``` - -2. Implement lifecycle callbacks for the widget. - - ```javascript - export default class FormAbility extends FormExtension { - onCreate(want) { - console.log('FormAbility onCreate'); - // Persistently store widget information for subsequent use, such as widget instance retrieval or update. - let obj = { - "title": "titleOnCreate", - "detail": "detailOnCreate" - }; - let formData = formBindingData.createFormBindingData(obj); - return formData; - } - onCastToNormal(formId) { - // Called when the widget host converts the temporary widget into a normal one. The widget provider should do something to respond to the conversion. - console.log('FormAbility onCastToNormal'); - } - onUpdate(formId) { - // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. - console.log('FormAbility onUpdate'); - let obj = { - "title": "titleOnUpdate", - "detail": "detailOnUpdate" - }; - let formData = formBindingData.createFormBindingData(obj); - formProvider.updateForm(formId, formData).catch((error) => { - console.log('FormAbility updateForm, error:' + JSON.stringify(error)); - }); - } - onVisibilityChange(newStatus) { - // Called when the widget host initiates an event about visibility changes. The widget provider should do something to respond to the notification. - console.log('FormAbility onVisibilityChange'); - } - onEvent(formId, message) { - // If the widget supports event triggering, override this method and implement the trigger. - console.log('FormAbility onEvent'); - } - onDestroy(formId) { - // Delete widget data. - console.log('FormAbility onDestroy'); - } - onConfigurationUpdated(config) { - console.log('FormAbility onConfigurationUpdated, config:' + JSON.stringify(config)); - } - } - ``` - -### Configuring the Widget Configuration File - -- Configure Extension ability information under **extensionAbilities** in the **module.json5** file. The internal field structure is described as follows: - - | Name | Description | Data Type | Default Value Allowed | - | ----------- | ------------------------------------------------------------ | ---------- | -------------------- | - | name | Name of the Extension ability. This field must be specified. | String | No | - | srcEnty | Path of the Extension ability lifecycle code. This field must be specified.| String | No | - | description | Description of the Extension ability. The value can be a string or a resource index to descriptions in multiple languages.| String | Yes (initial value: left empty)| - | icon | Index of the Extension ability icon file. | String | Yes (initial value: left empty)| - | label | Descriptive information about the Extension ability presented externally. The value can be a string or a resource index to the description.| String | Yes (initial value: left empty)| - | type | Type of the Extension ability. In the current development scenario, set this field to **form**.| String | No | - | permissions | Permissions required for abilities of another application to call the current ability. | String array| Yes (initial value: left empty)| - | metadata | Metadata (configuration information) of the Extension ability.| Object | Yes (initial value: left empty) | - - For a Form Extension ability, you must specify **metadata**. Specifically, set **name** to **ohos.extension.form** (fixed), and set **resource** to the index of the widget configuration information. - - Example configuration: - - ```json - "extensionAbilities": [{ - "name": "FormAbility", - "srcEnty": "./ets/FormAbility/FormAbility.ts", - "label": "$string:form_FormAbility_label", - "description": "$string:form_FormAbility_desc", - "type": "form", - "metadata": [{ - "name": "ohos.extension.form", - "resource": "$profile:form_config" - }] - }] - ``` - -- Configure the widget configuration information. **resource** in **metadata** specifies the index of the widget configuration information. For example, **$profile:form_config** means that **form_config.json** in the **resources/base/profile/** directory of the development view is used as the widget profile configuration file. - - The internal field structure is described as follows: - - | Name | Description | Data Type | Default Value Allowed | - | ------------------- | ------------------------------------------------------------ | ---------- | ------------------------ | - | name | Class name of the widget. The value is a string with a maximum of 127 bytes. | String | No | - | description | Description of the widget. The value can be a string or a resource index to descriptions in multiple languages. The value is a string with a maximum of 255 bytes.| String | Yes (initial value: left empty) | - | src | Full path of the UI code corresponding to the widget. | String | No | - | window | Window-related configurations. | Object | Yes | - | isDefault | Whether the widget is a default one. Each ability has only one default widget.
**true**: The widget is the default one.
**false**: The widget is not the default one.| Boolean | No | - | colorMode | Color mode of the widget.
**auto**: The widget adopts the auto-adaptive color mode.
**dark**: The widget adopts the dark color mode.
**light**: The widget adopts the light color mode.| String | Yes (initial value: **auto**)| - | supportDimensions | Grid styles supported by the widget.
**1 * 2**: indicates a grid with one row and two columns.
**2 * 2**: indicates a grid with two rows and two columns.
**2 * 4**: indicates a grid with two rows and four columns.
**4 * 4**: indicates a grid with four rows and four columns.| String array| No | - | defaultDimension | Default grid style of the widget. The value must be available in the **supportDimensions** array of the widget.| String | No | - | updateEnabled | Whether the widget can be updated periodically.
**true**: The widget can be updated at a specified interval (**updateDuration**) or at the scheduled time (**scheduledUpdateTime**). **updateDuration** takes precedence over **scheduledUpdateTime**.
**false**: The widget cannot be updated periodically.| Boolean | No | - | scheduledUpdateTime | Scheduled time to update the widget. The value is in 24-hour format and accurate to minute.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| String | Yes (initial value: **0:0**) | - | updateDuration | Interval to update the widget. The value is a natural number, in the unit of 30 minutes.
If the value is **0**, this field does not take effect.
If the value is a positive integer *N*, the interval is calculated by multiplying *N* and 30 minutes.
**updateDuration** takes precedence over **scheduledUpdateTime**. If both are specified, the value specified by **updateDuration** is used.| Number | Yes (initial value: **0**) | - | formConfigAbility | Link to a specific page of the application. The value is a URI. | String | Yes (initial value: left empty) | - | formVisibleNotify | Whether the widget is allowed to use the widget visibility notification. | String | Yes (initial value: left empty) | - | metaData | Metadata of the widget. This field contains the array of the **customizeData** field. | Object | Yes (initial value: left empty) | - - Example configuration: - - ```json - { - "forms": [{ - "name": "widget", - "description": "This is a widget.", - "src": "./js/widget/pages/index/index", - "window": { - "autoDesignWidth": true, - "designWidth": 720 - }, - "isDefault": true, - "colorMode": "auto", - "supportDimensions": ["2*2"], - "defaultDimension": "2*2", - "updateEnabled": true, - "scheduledUpdateTime": "10:30", - "formConfigAbility": "ability://ohos.samples.FormApplication.MainAbility" - }] - } - ``` - - -### Persistently Storing Widget Data - -A widget provider is usually started when it is needed to provide information about a widget. The Widget Manager supports multi-instance management and uses the widget ID to identify an instance. If the widget provider supports widget data modification, it must persistently store the data based on the widget ID, so that it can access the data of the target widget when obtaining, updating, or starting a widget. - -```javascript - onCreate(want) { - console.log('FormAbility onCreate'); - - let formId = want.parameters["ohos.extra.param.key.form_identity"]; - let formName = want.parameters["ohos.extra.param.key.form_name"]; - let tempFlag = want.parameters["ohos.extra.param.key.form_temporary"]; - // Persistently store widget data for subsequent use, such as widget instance retrieval or update. - // The storeFormInfo API is not implemented here. - storeFormInfo(formId, formName, tempFlag, want); - - let obj = { - "title": "titleOnCreate", - "detail": "detailOnCreate" - }; - let formData = formBindingData.createFormBindingData(obj); - return formData; - } -``` - -You should override **onDestroy** to implement widget data deletion. - -```javascript - onDestroy(formId) { - console.log('FormAbility onDestroy'); - - // You need to implement the code for deleting the persistent widget data. - // The deleteFormInfo API is not implemented here. - deleteFormInfo(formId); - } -``` - -For details about how to implement persistent data storage, see [Persisting Preferences Data](../database/data-persistence-by-preferences.md). - -The **Want** object passed in by the widget host to the widget provider contains a flag that specifies whether the requested widget is normal or temporary. - -- Normal widget: a widget persistently used by the widget host - -- Temporary widget: a widget temporarily used by the widget host - -Data of a temporary widget will be deleted on the Widget Manager if the widget framework is killed and restarted. The widget provider, however, is not notified of the deletion and still keeps the data. Therefore, the widget provider needs to clear the data of temporary widgets proactively if the data has been kept for a long period of time. If the widget host has converted a temporary widget into a normal one, the widget provider should change the widget data from temporary storage to persistent storage. Otherwise, the widget data may be deleted by mistake. - -### Updating Widget Data - -When an application initiates a scheduled or periodic update, the application obtains the latest data and calls **updateForm** to update the widget. The code snippet is as follows: - -```javascript -onUpdate(formId) { - // Override this method to support scheduled updates, periodic updates, or updates requested by the widget host. - console.log('FormAbility onUpdate'); - let obj = { - "title": "titleOnUpdate", - "detail": "detailOnUpdate" - }; - let formData = formBindingData.createFormBindingData(obj); - // Call the updateForm() method to update the widget. Only the data passed through the input parameter is updated. Other information remains unchanged. - formProvider.updateForm(formId, formData).catch((error) => { - console.log('FormAbility updateForm, error:' + JSON.stringify(error)); - }); -} -``` - -### Developing the Widget UI Page - -You can use HML, CSS, and JSON to develop the UI page for a JavaScript-programmed widget. - -> **NOTE** -> -> Only the JavaScript-based web-like development paradigm is supported when developing the widget UI. - - - HML file: - ```html -
- -
- -
-
- {{title}} - {{detail}} -
-
-
- ``` - - - CSS file: - - ```css -.container { - flex-direction: column; - justify-content: center; - align-items: center; -} - -.bg-img { - flex-shrink: 0; - height: 100%; -} - -.container-inner { - flex-direction: column; - justify-content: flex-end; - align-items: flex-start; - height: 100%; - width: 100%; - padding: 12px; -} - -.title { - font-size: 19px; - font-weight: bold; - color: white; - text-overflow: ellipsis; - max-lines: 1; -} - -.detail_text { - font-size: 16px; - color: white; - opacity: 0.66; - text-overflow: ellipsis; - max-lines: 1; - margin-top: 6px; -} - ``` - - - JSON file: - ```json - { - "data": { - "title": "TitleDefault", - "detail": "TextDefault" - }, - "actions": { - "routerEvent": { - "action": "router", - "abilityName": "MainAbility", - "params": { - "message": "add detail" - } - } - } - } - ``` - -Now you've got a widget shown below. - -![fa-form-example](figures/fa-form-example.png) - -### Developing Widget Events - -You can set router and message events for components on a widget. The router event applies to ability redirection, and the message event applies to custom click events. The key steps are as follows: - -1. Set the **onclick** field in the HML file to **routerEvent** or **messageEvent**, depending on the **actions** settings in the JSON file. -2. Set the router event. - - **action**: **"router"**, which indicates a router event. - - **abilityName**: target ability name, for example, **MainAbility**, which is the default main ability name in DevEco Studio for the stage model. - - **params**: custom parameters of the target ability. Set them as required. The value can be obtained from **parameters** in **want** used for starting the target ability. For example, in the lifecycle function **onCreate** of the main ability in the stage model, you can obtain **want** and its **parameters** field. -3. Set the message event. - - **action**: **"message"**, which indicates a message event. - - **params**: custom parameters of the message event. Set them as required. The value can be obtained from **message** in the widget lifecycle function **onEvent**. - -The code snippet is as follows: - - - HML file: - ```html -
- -
- -
-
- {{title}} - {{detail}} -
-
-
- ``` - - - JSON file: - ```json - { - "data": { - "title": "TitleDefault", - "detail": "TextDefault" - }, - "actions": { - "routerEvent": { - "action": "router", - "abilityName": "MainAbility", - "params": { - "message": "add detail" - } - }, - "messageEvent": { - "action": "message", - "params": { - "message": "add detail" - } - } - } - } - ``` diff --git a/en/application-dev/ability-deprecated/stage-serviceextension.md b/en/application-dev/ability-deprecated/stage-serviceextension.md deleted file mode 100644 index 9c59d949bab7c362f922cc4b52b024b5c411101b..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/stage-serviceextension.md +++ /dev/null @@ -1,75 +0,0 @@ -# Service Extension Ability Development - -## When to Use -`ExtensionAbility` is the base class of the new Extension component in the stage model. It is used to process missions without UIs. The lifecycle of an Extension ability is simple and does not involve foreground or background states. `ServiceExtensionAbility` is extended from `ExtensionAbility`. - -You can customize a class that inherits from `ServiceExtensionAbility` and override the lifecycle callbacks in the base class to perform service logic operations during the initialization, connection, and disconnection processes. - -## Available APIs - -**Table 1** ServiceExtensionAbility lifecycle APIs -|API|Description| -|:------|:------| -|onCreate(want: Want): void|Called for the initialization when `startAbility` or `connectAbility` is invoked for a given ability for the first time.| -|onRequest(want: Want, startId: number): void|Called each time `startAbility` is invoked for a given ability. The initial value of `startId` is `1`, and the value is incremented by one each time `startAbility` is invoked for that ability.| -|onConnect(want: Want): rpc.RemoteObject|Called when `connectAbility` is invoked for a given ability. This callback is not invoked for repeated calling of `connectAbility` for a specific ability. However, it will be invoked unless `connectAbility` is called after the ability has been disconnected using `disconnectAbility`. The returned result is a `RemoteObject`.| -|onDisconnect(want: Want): void|Called when `disconnectAbility` is called for a given ability. If the Extension ability is started by `connectAbility` and is not bound to other applications, the `onDestroy` callback will also be triggered to destroy the Extension ability.| -|onDestroy(): void|Called when `terminateSelf` is invoked to terminate the ability.| - - -## Constraints - -OpenHarmony does not support creation of a Service Extension ability for third-party applications. - - -## How to Develop - -1. Declare the Service Extension ability in the `module.json5` file by setting its `type` attribute to `service`. The following is a configuration example of the `module.json5` file: - - - ```json - "extensionAbilities":[{ - "name": "ServiceExtAbility", - "icon": "$media:icon", - "description": "service", - "type": "service", - "exported": true, - "srcEnty": "./ets/ServiceExtAbility/ServiceExtAbility.ts" - }] - ``` - - -2. Customize a class that inherits from `ServiceExtensionAbility` in the .ts file in the directory where the Service Extension ability is defined (`entry\src\main\ets\ServiceExtAbility\ServiceExtAbility.ts` by default) and override the lifecycle callbacks of the base class. The code sample is as follows: - - ```js - import ServiceExtensionAbility from '@ohos.application.ServiceExtensionAbility' - import rpc from '@ohos.rpc' - - class StubTest extends rpc.RemoteObject { - constructor(des) { - super(des); - } - onRemoteRequest(code, data, reply, option) { - } - } - - class ServiceExtAbility extends ServiceExtensionAbility { - onCreate(want) { - console.log('onCreate, want:' + want.abilityName); - } - onRequest(want, startId) { - console.log('onRequest, want:' + want.abilityName); - } - onConnect(want) { - console.log('onConnect , want:' + want.abilityName); - return new StubTest("test"); - } - onDisconnect(want) { - console.log('onDisconnect, want:' + want.abilityName); - } - onDestroy() { - console.log('onDestroy'); - } - } - ``` - diff --git a/en/application-dev/ability-deprecated/wantagent.md b/en/application-dev/ability-deprecated/wantagent.md deleted file mode 100644 index 334306dc5bf294cad1f41bf371db13d892af756a..0000000000000000000000000000000000000000 --- a/en/application-dev/ability-deprecated/wantagent.md +++ /dev/null @@ -1,86 +0,0 @@ -# WantAgent Development -## When to Use -The **WantAgent** class encapsulates want information that specifies a particular action, which can be starting an ability or publishing a common event. You can either call **wantAgent.trigger** to trigger a **WantAgent** directly or add a **WantAgent** to a notification so that it will be triggered when users tap the notification. - -## Available APIs -| API | Description| -| ---------------------------------------------------------------------------------------------- | ----------- | -| getWantAgentInfo(info: WantAgentInfo, callback: AsyncCallback\) | Creates a **WantAgent** object. This API uses an asynchronous callback to return the result.| -| getWantAgent(info: WantAgentInfo): Promise\ | Creates a **WantAgent** object. This API uses a promise to return the result.| -| trigger(agent: WantAgent, triggerInfo: TriggerInfo, callback?: Callback\) | Triggers a **WantAgent** object.| - -## How to Develop -1. Import the **WantAgent** module. - - ``` - import wantAgent from '@ohos.wantAgent'; - ``` - -2. Create a **WantAgentInfo** object that will be used for starting an ability. For details about the data types and parameters of **WantAgentInfo**, see [WantAgent](../reference/apis/js-apis-wantAgent.md#wantagentinfo). - - ``` - private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations. - - // wantAgentInfo - var wantAgentInfo = { - wants: [ - { - deviceId: "", - bundleName: "com.example.test", - abilityName: "com.example.test.MainAbility", - action: "", - entities: [], - uri: "", - parameters: {} - } - ], - operationType: wantAgent.OperationType.START_ABILITY, - requestCode: 0, - wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG] - } - ``` - -3. Create a **WantAgentInfo** object for publishing a common event. - - ``` - private wantAgentObj = null // Save the WantAgent object created. It will be used to complete the trigger operations. - - // wantAgentInfo - var wantAgentInfo = { - wants: [ - { - action: "event_name", // Set the action name. - parameters: {} - } - ], - operationType: wantAgent.OperationType.SEND_COMMON_EVENT, - requestCode: 0, - wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG] - } - ``` - -4. Create a **WantAgent** object and save the returned **wantAgentObj** for subsequent trigger operations. - - ``` - // Create a WantAgent object. - wantAgent.getWantAgent(wantAgentInfo, (err, wantAgentObj) => { - if (err.code) { - console.error("[WantAgent]getWantAgent err=" + JSON.stringify(err)) - } else { - console.log("[WantAgent]getWantAgent success") - this.wantAgentObj = wantAgentObj - } - }) - ``` - -5. Trigger the **WantAgent** object. - - ``` - // Trigger the WantAgent object. - var triggerInfo = { - code:0 - } - wantAgent.trigger(wantAgentObj, triggerInfo, (completeData) => { - console.log("[WantAgent]getWantAgent success, completeData: ", + JSON.stringify(completeData)) - }) - ```