diff --git a/en/application-dev/ability/fa-pageability.md b/en/application-dev/ability/fa-pageability.md index 1fe34335238f17e3318128b9c52cf59ba00b12e8..f3930179f3a976792ddde6ea345a67541199649e 100644 --- a/en/application-dev/ability/fa-pageability.md +++ b/en/application-dev/ability/fa-pageability.md @@ -2,13 +2,13 @@ ## Overview ### Concepts -The Page ability has the ArkUI and therefore provides the capability of interacting with users. When you create an ability in the integrated development environment (IDE), the IDE automatically creates template code. The capabilities related to the Page ability are exposed through the singleton **featureAbility**, and the lifecycle callbacks are exposed through the callback functions in **app.js/app.ets**. +The Page ability implements the ArkUI and provides the capability of interacting with users. When you create an ability in the integrated development environment (IDE), the IDE automatically creates template code. The capabilities related to the Page ability are exposed through the singleton **featureAbility**, and the lifecycle callbacks are exposed through the callbacks in **app.js/app.ets**. ### Page Ability Lifecycle -The ability lifecycle is a general term for all states of an ability (either a Page or a Service ability), such as **INACTIVE**, **ACTIVE**, and **BACKGROUND**. +**Ability Lifecycle** -The following figure shows the lifecycle state transition of the Page ability. +The ability lifecycle is a general term for all states of an 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) @@ -25,11 +25,11 @@ Description of ability lifecycle states: - **BACKGROUND**: The ability returns to the background. After being re-activated, the ability enters the **ACTIVE** state. After being destroyed, the ability enters the **INITIAL** state. -**The following figure shows the lifecycle of the Page ability.** +**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 callback functions provided by the Page ability in **app.js/app.ets**. +You can override the lifecycle callbacks provided by the Page ability in the **app.js/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. ## Development Guidelines ### Available APIs @@ -46,48 +46,48 @@ You can override the lifecycle callback functions provided by the Page ability i ### Starting a Local Page Ability -* Modules to Import +**Modules to Import** +```js + import featureAbility from '@ohos.ability.featureAbility' ``` -import featureAbility from '@ohos.ability.featureAbility' -``` -* Example + +**Example** ```javascript -import featureAbility from '@ohos.ability.featureAbility' -featureAbility.startAbility({ + import featureAbility from '@ohos.ability.featureAbility' + featureAbility.startAbility({ want: { action: "", entities: [""], type: "", options: { - // Grant the permission to read the URI. + // Grant the permission to perform read operations on the URI. authReadUriPermission: true, - // Grant the permission to write the URI. + // Grant the permission to perform write operations on the URI. authWriteUriPermission: true, - // Forward the intent result to the origin ability. + // Support forwarding the intent result to the ability. abilityForwardResult: true, - // Mark the ability start-up triggered by continuation. + // Enable abiligy continuation. abilityContinuation: true, // Specify that a component does not belong to ohos. notOhosComponent: true, - // Specify whether an ability is started. + // Specify that an ability is started. abilityFormEnabled: true, - // Grant the permission to persist the URI. + // Grant the permission for possible persisting on the URI. authPersistableUriPermission: true, - // Grant the permission to persist the URI. + // Grant the permission for possible persisting on the prefix URI. authPrefixUriPermission: true, - // Support distributed scheduling and start-up across multiple devices. + // Support distributed scheduling system startup on multiple devices. abilitySliceMultiDevice: true, - // An ability using the Service template is started regardless of whether the - // host application has been started. + // A service ability is started regardless of whether the host application has been started. startForegroundAbility: true, // Install the specified ability if it is not installed. installOnDemand: true, - // Return the result to the origin ability slice. + // Return the result to the ability slice. abilitySliceForwardResult: true, - // Install the specified ability with the background mode if it is not installed. + // Install the specified ability with background mode if it is not installed. installWithBackgroundMode: true }, deviceId: "", @@ -95,14 +95,16 @@ featureAbility.startAbility({ abilityName: "com.example.startability.MainAbility", uri: "" }, -}, -); + }, + ); ``` + You can also include **parameters** in the **want** parameter and set its value in the key-value format. -* Example +**Example** + ```javascript -import featureAbility from '@ohos.ability.featureAbility' -featureAbility.startAbility({ + import featureAbility from '@ohos.ability.featureAbility' + featureAbility.startAbility({ want: { bundleName: "com.example.startability", @@ -111,44 +113,111 @@ featureAbility.startAbility({ abilityName: "com.example.startability.MainAbility" } }, -}, -); + }, + ); ``` -### Starting a Remote Page Ability +### Starting a Remote Page Ability (Applying only to System Applications) +>Note: The **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. Therefore, remote Page ability startup applies only to system applications. -* Modules to Import +**Modules to Import** ``` -import featureAbility from '@ohos.ability.featureAbility' + import featureAbility from '@ohos.ability.featureAbility' + import deviceManager from '@ohos.distributedHardware.deviceManager'; ``` -* Example +**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'); + } +``` -```javascript -var promise = await featureAbility.startAbility({ - want: - { - deviceId: this.deviceId, - bundleName: "com.example.test", - abilityName: "com.example.test.MainAbility", - }, -} -); +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) { + } else { + 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 2** Lifecycle callback functions +**Table 2** Lifecycle callbacks | API | Description | | ------------ | ------------------------------------------------------------ | -| onShow() | Invoked when the ability is switched from the background to the foreground. In this case, the ability is visible to users.| -| onHide() | Invoked when the ability is switched from the foreground to the background. In this case, the ability is invisible.| -| onDestroy() | Invoked when the ability is destroyed. In this callback, you can make preparations for app exit, such as recycling resources and clearing the cache.| -| onCreate() | Invoked when the ability is created for the first time. You can initialize the application in this callback.| -| onInactive() | Invoked when the ability loses focus. An ability loses focus before entering the background state.| -| onActive() | Invoked when the ability is switched to the foreground and gains focus. | - -* Example -You need to override the lifecycle callback functions in **app.js/app.ets**. The IDE template generates **onCreate()** and **onDestroy()** by default. You need to override the other functions. +| 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.| +| onDestroy() | Called when the ability is destroyed. In this callback, you can make preparations for app 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 before entering the background state.| +| onActive() | Called when the ability is switched to the foreground and gains focus. | + +**Example** +You need to override the lifecycle callbacks in **app.js/app.ets**. The IDE template generates **onCreate()** and **onDestroy()** by default. You need to override the other callbacks. + ```javascript export default { onCreate() { @@ -174,6 +243,6 @@ export default { ### Development Example The following sample is provided to help you better understand how to develop a Page ability: -- [DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS) +[DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS) This sample describes how to start a local ability and remote ability. diff --git a/en/application-dev/ability/fa-serviceability.md b/en/application-dev/ability/fa-serviceability.md index 41811571ccd7bc2b48bead35cd5c8c77a6e0a516..d68ea608eb895478e0c892f4ded632370771f6da 100644 --- a/en/application-dev/ability/fa-serviceability.md +++ b/en/application-dev/ability/fa-serviceability.md @@ -1,34 +1,27 @@ # Service Ability Development -## Basic Concepts +## 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 remain running in the background even after the user switches to another application. -## Creating a Service Ability +## Available APIs -1. Create a child class of the **Ability** class and override the following Service ability-related lifecycle callbacks to implement your own logic for processing requests to interact with your Service ability: - - - onStart() - - This callback is invoked for initializing a Service ability when the Service ability is being created. This callback is invoked only once in the entire lifecycle of a Service ability. The **Want** object passed to this callback must be null. - - - onCommand() - - This callback is invoked every time a Service ability is created on a client. You can calculate calling statistics and perform initialization operations in this callback. - - - onConnect() - - This callback is invoked when another ability is connected to the Service ability. It returns an **IRemoteObject**. You can use this callback to generate a channel for the other ability to interact with the Service ability during inter-process communication (IPC). An ability can connect to the same Service ability for multiple times. When the first client is connected to a Service ability, the system calls **onConnect()** to generate an **IRemoteObject** for the Service ability, and the generated **IRemoteObject** will then be cached and used for all clients that are connected to this Service ability without having to call **onConnect()** again. - - - onDisconnect() - - This callback is invoked when another ability is disconnected from the Service ability. +**Table 1** Service ability lifecycle callbacks +|API|Description| +|:------|:------| +|onStart|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. The **Want** object passed to this callback must be null.| +|onCommand|Called every time a Service ability is created on a client. You can calculate calling statistics and perform initialization operations in this callback.| +|onConnect|Called when another ability is connected to the Service ability.| +|onDisconnect|Called when another ability is disconnected from the Service ability.| +|onStop|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.| - - onStop() +## How to Develop - This callback is invoked when a Service ability is being destroyed. You should override this callback for your Service ability to clear its resources, such as threads and registered listeners. +### Creating a Service Ability +1. Create a child class of the **Ability** class and override the following Service ability-related lifecycle callbacks to implement your own logic for processing requests to interact with your Service ability: + The following code snippet shows how to create a Service ability: - + ```javascript export default { onStart(want) { @@ -49,11 +42,11 @@ A Service ability is used to run tasks in the background, such as playing music } ``` -2. Register a Service ability. +2. Register a Service ability. - You must declare your Service ability in the **config.json** file by setting its **type** attribute to **service**. - - ```javascript + You must declare your Service ability in the **config.json** file by setting its **type** attribute to **service**. + + ```javascript { "module": { "abilities": [ @@ -68,14 +61,13 @@ A Service ability is used to run tasks in the background, such as playing music } ... } - ``` + ``` - -## Starting the Service Ability +### Starting a Service ability -The **Ability** class provides the **startAbility()** method for you to start another Service ability by passing a **Want** object. +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. The meanings of the parameters are as follows: @@ -86,7 +78,7 @@ The following code snippet shows how to start a Service ability running on the l ```javascript import featureAbility from '@ohos.ability.featureability'; -var promise = await featureAbility.startAbility( +let promise = await featureAbility.startAbility( { want: { @@ -97,29 +89,49 @@ var promise = await featureAbility.startAbility( ); ``` -- After the preceding code is executed, the **startAbility()** method is called to start the Service ability. - - If the Service ability is not running, the system calls **onStart()** to initialize the Service ability, and then calls **onCommand()** on the Service ability. - - If the Service ability is running, the system directly calls **onCommand()** on the Service ability. +After the preceding code is executed, the **startAbility()** API is called to start the Service ability. +- If the Service ability is not running, the system calls **onStart()** to initialize the Service ability, and then calls **onCommand()** on the Service ability. +- If the Service ability is running, the system directly calls **onCommand()** on the Service ability. + -- Stopping a Service ability - Once created, the Service ability keeps running in the background. The system does not stop or destroy it unless memory resources must be reclaimed. You can call **terminateAbility()** on a Service ability to stop it or call **stopAbility()** on another ability to stop the specified Service ability. +### Stopping a Service ability + + Once created, the Service ability keeps running in the background. The system does not stop or destroy it unless memory resources must be reclaimed. You can call **terminateSelf()** on a Service ability to stop it or call **stopAbility()** on another ability to stop the specified Service ability. -## Connecting to a Local Service Ability +### Connecting to a Local Service Ability If you need to connect a Service ability to a Page ability or to a Service ability in another application, you must first implement the **IAbilityConnection** API for the connection. A Service ability allows other abilities to connect to it through **connectAbility()**. -When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the method. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. +When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. The following code snippet shows how to implement the callbacks: ```javascript -var mRemote; +let mRemote; function onConnectCallback(element, remote){ - console.log('ConnectAbility onConnect Callback') + console.log('onConnectLocalService onConnectDone element: ' + element); + console.log('onConnectLocalService onConnectDone remote: ' + remote); mRemote = remote; + if (mRemote == null) { + prompt.showToast({ + message: "onConnectLocalService not connected yet" + }); + return; + } + let option = new rpc.MessageOption(); + let data = new rpc.MessageParcel(); + let reply = new rpc.MessageParcel(); + data.writeInt(1); + data.writeInt(99); + await mRemote.sendRequest(1, data, reply, option); + let msg = reply.readInt(); + prompt.showToast({ + message: "onConnectLocalService connect result: " + msg, + duration: 3000 + }); } function onDisconnectCallback(element){ @@ -135,7 +147,7 @@ The following code snippet shows how to connect to a local Service ability: ```javascript import featureAbility from '@ohos.ability.featureability'; -var connId = featureAbility.connectAbility( +let connId = featureAbility.connectAbility( { bundleName: "com.jstest.serviceability", abilityName: "com.jstest.serviceability.MainAbility", @@ -155,7 +167,7 @@ The following code snippet shows how the Service ability instance returns itself ```javascript import rpc from "@ohos.rpc"; -var mMyStub; +let mMyStub; export default { onStart(want) { class MyStub extends rpc.RemoteObject{ @@ -166,6 +178,16 @@ export default { return null; } onRemoteRequest(code, message, reply, option) { + console.log("ServiceAbility onRemoteRequest called"); + if (code === 1) { + let op1 = data.readInt(); + let op2 = data.readInt(); + console.log("op1 = " + op1 + ", op2 = " + op2); + reply.writeInt(op1 + op2); + } else { + console.log("ServiceAbility unknown request code"); + } + return true; } } mMyStub = new MyStub("ServiceAbility-test"); @@ -186,19 +208,38 @@ export default { } ``` -## Connecting to a Remote Service Ability +### Connecting to a Remote Service Ability (Applying only to System Applications) +>Note: The **getTrustedDeviceListSync** API of the **DeviceManager** class is open only to system applications. Therefore, remote Service ability startup applies only to system applications. If you need to connect a Service ability to a Page ability on another device or to a Service ability in another application on another device, you must first implement the **IAbilityConnection** interface for the connection. A Service ability allows other abilities on another device to connect to it through **connectAbility()**. -When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the method. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. +When calling **connectAbility()**, you should pass a **Want** object containing information about the target Service ability and an **IAbilityConnection** object to the API. **IAbilityConnection** provides the following callbacks that you should implement: **onConnect()**, **onDisconnect()**, and **onFailed()**. The **onConnect()** callback is invoked when a Service ability is connected, **onDisconnect()** is invoked when a Service ability is unexpectedly disconnected, and **onFailed()** is invoked when a connection to a Service ability fails. The following code snippet shows how to implement the callbacks: -```javascript -var mRemote; +```ts +let mRemote; function onConnectCallback(element, remote){ - console.log('ConnectRemoteAbility onConnect Callback') + console.log('onConnectLocalService onConnectDone element: ' + element); + console.log('onConnectLocalService onConnectDone remote: ' + remote); mRemote = remote; + if (mRemote == null) { + prompt.showToast({ + message: "onConnectLocalService not connected yet" + }); + return; + } + let option = new rpc.MessageOption(); + let data = new rpc.MessageParcel(); + let reply = new rpc.MessageParcel(); + data.writeInt(1); + data.writeInt(99); + await mRemote.sendRequest(1, data, reply, option); + let msg = reply.readInt(); + prompt.showToast({ + message: "onConnectLocalService connect result: " + msg, + duration: 3000 + }); } function onDisconnectCallback(element){ @@ -210,17 +251,35 @@ function onFailedCallback(code){ } ``` -The **Want** of the target Service ability must contain the remote **deviceId**, which can be obtained through **deviceManager**. +The **Want** of the target Service ability must contain the remote **deviceId**, which can be obtained 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"); + } +} +``` The following code snippet shows how to connect to a remote Service ability: -```javascript +```ts import featureAbility from '@ohos.ability.featureability'; -var connId = featureAbility.connectAbility( +let connId = featureAbility.connectAbility( { - deviceId: deviceId, - bundleName: "com.jstest.serviceability", - abilityName: "com.jstest.serviceability.MainAbility", + deviceId: getRemoteDeviceId(), + bundleName: "ohos.samples.etsDemo", + abilityName: "ohos.samples.etsDemo.ServiceAbility", }, { onConnect: onConnectCallback, @@ -229,48 +288,107 @@ var connId = featureAbility.connectAbility( }, ); ``` +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) { + } else { + 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'); +} +``` 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 a default implementation of the **IRemoteObject** interface. You can inherit **rpc.RemoteObject** to implement your own class of **IRemoteObject**. The following code snippet shows how the Service ability instance returns itself to the calling ability: -```javascript +```ts import rpc from "@ohos.rpc"; -var mMyStub; -export default { - onStart(want) { - class MyStub extends rpc.RemoteObject{ - constructor(des) { - if (typeof des === 'string') { - super(des); - } - return null; - } - onRemoteRequest(code, message, reply, option) { - } +class FirstServiceAbilityStub extends rpc.RemoteObject{ + constructor(des) { + if (typeof des === 'string') { + super(des); + } else { + return null; } - mMyStub = new MyStub("ServiceAbility-test"); + } + onRemoteRequest(code, data, reply, option) { + console.log("ServiceAbility onRemoteRequest called"); + if (code === 1) { + let op1 = data.readInt(); + let op2 = data.readInt(); + console.log("op1 = " + op1 + ", op2 = " + op2); + reply.writeInt(op1 + op2); + } else { + console.log("ServiceAbility unknown request code"); + } + return true; + } +} + +export default { + onStart() { + console.info('ServiceAbility onStart'); }, - onCommand(want, restart, startId) { - console.log('ServiceAbility onCommand'); + onStop() { + console.info('ServiceAbility onStop'); }, onConnect(want) { - console.log('ServiceAbility OnConnect'); - return mMyStub; - }, - onDisconnect() { - console.log('ServiceAbility OnDisConnect'); + console.log("ServiceAbility onConnect"); + try { + let value = JSON.stringify(want); + console.log("ServiceAbility want:" + value); + } catch(error) { + console.log("ServiceAbility error:" + error); + } + return new FirstServiceAbilityStub("first ts service stub"); }, - onStop() { - console.log('ServiceAbility onStop'); + onDisconnect(want) { + console.log("ServiceAbility onDisconnect"); + let value = JSON.stringify(want); + console.log("ServiceAbility want:" + value); }, -} + onCommand(want, startId) { + console.info('ServiceAbility onCommand'); + let value = JSON.stringify(want); + console.log("ServiceAbility want:" + value); + console.log("ServiceAbility startId:" + startId); + } +}; ``` ## Development Example -The following sample is provided to help you better understand how to develop a Service ability: +### The following sample is provided to help you better understand how to develop a Service ability: - [eTSServiceAbility](https://gitee.com/openharmony/app_samples/tree/master/ability/eTSServiceAbility) @@ -279,3 +397,14 @@ This **eTSServiceAbility** sample shows how to: Create a local Service ability in the **service.ts** file in the **ServiceAbility** directory. Encapsulate the process of starting and connecting to the local Service ability in the **MainAbility** directory. + + +### The following sample is provided to help you better understand how to develop a remote Service ability: + +- [DMS](https://gitee.com/openharmony/app_samples/tree/master/ability/DMS) + +This **DMS** sample shows how to: + +Create a remote Service ability in the **service.ts** file in the **ServiceAbility** directory. + +Encapsulate the process of connecting to the remote Service ability in the **RemoteAbility** directory.