diff --git a/en/application-dev/connectivity/ipc-rpc-development-guideline.md b/en/application-dev/connectivity/ipc-rpc-development-guideline.md index 89bff0d4a168c74309f6bc711a3725fd4c9aad1b..b9bbb0608dfb83ba6d2198b063e68c4b324bbd88 100644 --- a/en/application-dev/connectivity/ipc-rpc-development-guideline.md +++ b/en/application-dev/connectivity/ipc-rpc-development-guideline.md @@ -1,4 +1,4 @@ -# IPC & RPC Development +# IPC & RPC Development Guidelines ## When to Use @@ -11,8 +11,8 @@ Table 1 Native IPC APIs | Class| API| Description| | -------- | -------- | -------- | -| [IRemoteBroker](../reference/apis/js-apis-rpc.md#iremotebroker) | sptr<IRemoteObject> AsObject() | Holder of a remote proxy object. If you call this API on the stub, the **RemoteObject** is returned; if you call this API on the proxy, the proxy object is returned.| -| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Callback used to process a request from the proxy and return the result. Derived classes need to override this API.| +| [IRemoteBroker](../reference/apis/js-apis-rpc.md#iremotebroker) | sptr<IRemoteObject> AsObject() | Obtains the holder of a remote proxy object. If you call this API on the stub, the **RemoteObject** is returned; if you call this API on the proxy, the proxy object is returned.| +| IRemoteStub | virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) | Called to process a request from the proxy and return the result. Derived classes need to override this API.| | IRemoteProxy | | Service proxy class, which is derived from the **IRemoteProxy** class.| @@ -29,7 +29,7 @@ Table 1 Native IPC APIs external_deps = [ "ipc:ipc_single", ] - + #RPC scenario external_deps = [ "ipc:ipc_core", @@ -50,12 +50,12 @@ Table 1 Native IPC APIs ```c++ #include "iremote_broker.h" - + // Define message codes. - const int TRANS_ID_PING_ABILITY = 5 - + const int TRANS_ID_PING_ABILITY = 5; + const std::string DESCRIPTOR = "test.ITestAbility"; - + class ITestAbility : public IRemoteBroker { public: // DECLARE_INTERFACE_DESCRIPTOR is mandatory, and the input parameter is std::u16string. @@ -71,13 +71,13 @@ Table 1 Native IPC APIs ```c++ #include "iability_test.h" #include "iremote_stub.h" - + class TestAbilityStub : public IRemoteStub { public: virtual int OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) override; int TestPingAbility(const std::u16string &dummy) override; }; - + int TestAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { @@ -98,12 +98,12 @@ Table 1 Native IPC APIs ```c++ #include "iability_server_test.h" - + class TestAbility : public TestAbilityStub { public: int TestPingAbility(const std::u16string &dummy); } - + int TestAbility::TestPingAbility(const std::u16string &dummy) { return 0; } @@ -117,7 +117,7 @@ Table 1 Native IPC APIs #include "iability_test.h" #include "iremote_proxy.h" #include "iremote_object.h" - + class TestAbilityProxy : public IRemoteProxy { public: explicit TestAbilityProxy(const sptr &impl); @@ -125,12 +125,12 @@ Table 1 Native IPC APIs private: static inline BrokerDelegator delegator_; // Use the iface_cast macro. } - + TestAbilityProxy::TestAbilityProxy(const sptr &impl) : IRemoteProxy(impl) { } - + int TestAbilityProxy::TestPingAbility(const std::u16string &dummy){ MessageOption option; MessageParcel dataParcel, replyParcel; @@ -149,7 +149,7 @@ Table 1 Native IPC APIs // Register the TestAbilityStub instance with the SystemAbilityManager on the same device as the SA. auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); samgr->AddSystemAbility(saId, new TestAbility()); - + // Register the TestAbilityStub instance with the SystemAbilityManager on a different device. auto samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); ISystemAbilityManager::SAExtraProp saExtra; @@ -166,10 +166,10 @@ Table 1 Native IPC APIs sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); sptr remoteObject = samgr->GetSystemAbility(saId); sptr testAbility = iface_cast(remoteObject); // Use the iface_cast macro to convert the proxy to a specific type. - + // Obtain the proxy of the SA registered with any other devices. sptr samgr = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - + // networkId is the device identifier and can be obtained through GetLocalNodeDeviceInfo. sptr remoteObject = samgr->GetSystemAbility(saId, networkId); sptr proxy(new TestAbilityProxy(remoteObject)); // Construct a proxy. @@ -180,59 +180,97 @@ Table 1 Native IPC APIs 1. Add dependencies. ```ts - import rpc from "@ohos.rpc" - import featureAbility from "@ohos.ability.featureAbility" + import rpc from "@ohos.rpc"; + // Import @ohos.ability.featureAbility only for the application developed based on the FA model. + // import featureAbility from "@ohos.ability.featureAbility"; ``` - + If you use the stage model, you need to obtain the context. The sample code is as follows: + + ```ts + import Ability from "@ohos.app.ability.UIAbility"; + + export default class MainAbility extends Ability { + onCreate(want, launchParam) { + console.log("[Demo] MainAbility onCreate"); + globalThis.context = this.context; + } + onDestroy() { + console.log("[Demo] MainAbility onDestroy"); + } + onWindowStageCreate(windowStage) { + // Main window is created, set main page for this ability + console.log("[Demo] MainAbility onWindowStageCreate"); + } + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + console.log("[Demo] MainAbility onWindowStageDestroy"); + } + onForeground() { + // Ability has brought to foreground + console.log("[Demo] MainAbility onForeground"); + } + onBackground() { + // Ability has back to background + console.log("[Demo] MainAbility onBackground"); + } + } + ``` 2. Bind the desired ability. - Construct the **want** variable, and specify the bundle name and component name of the application where the ability is located. If cross-device communication is involved, also specify the network ID of the target device, which can be obtained through **deviceManager**. Then, construct the **connect** variable, and specify the callback that is called when the binding is successful, the binding fails, or the ability is disconnected. After that, call the API provided by **featureAbility** to bind an ability. + Construct the **want** variable, and specify the bundle name and component name of the application where the ability is located. If cross-device communication is involved, also specify the network ID of the target device, which can be obtained through **deviceManager**. Then, construct the **connect** variable, and specify the callback that is called when the binding is successful, the binding fails, or the ability is disconnected. If you use the FA model, call the API provided by **featureAbility** to bind an ability. If you use the stage model, obtain a service instance through **Context**, and then call the API provided by **featureAbility** to bind an ability. ```ts - import rpc from "@ohos.rpc" - import featureAbility from "@ohos.ability.featureAbility" - - let proxy = null - let connectId = null - + import rpc from "@ohos.rpc"; + // Import @ohos.ability.featureAbility only for the application developed based on the FA model. + // import featureAbility from "@ohos.ability.featureAbility"; + + let proxy = null; + let connectId = null; + // Bind the ability on a single device. let want = { // Enter the bundle name and ability name. "bundleName": "ohos.rpc.test.server", "abilityName": "ohos.rpc.test.server.ServiceAbility", - } + }; let connect = { onConnect:function(elementName, remote) { - proxy = remote + proxy = remote; }, onDisconnect:function(elementName) { }, onFailed:function() { - proxy = null + proxy = null; } - } - connectId = featureAbility.connectAbility(want, connect) - + }; + // Use this method to connect to the ability in the FA model. + // connectId = featureAbility.connectAbility(want, connect); + + connectId = globalThis.context.connectServiceExtensionAbility(want,connect); + // If you're binding the ability across devices, use deviceManager to obtain the network ID of the target device. - import deviceManager from '@ohos.distributedHardware.deviceManager' + import deviceManager from '@ohos.distributedHardware.deviceManager'; function deviceManagerCallback(deviceManager) { - let deviceList = deviceManager.getTrustedDeviceListSync() - let networkId = deviceList[0].networkId + let deviceList = deviceManager.getTrustedDeviceListSync(); + let networkId = deviceList[0].networkId; let want = { "bundleName": "ohos.rpc.test.server", "abilityName": "ohos.rpc.test.service.ServiceAbility", "networkId": networkId, "flags": 256 - } - connectId = featureAbility.connectAbility(want, connect) + }; + // The ID returned after the connection is set up must be saved. The ID will be passed for service disconnection. + // Use this method to connect to the ability in the FA model. + // connectId = featureAbility.connectAbility(want, connect); + + connectId = globalThis.context.connectServiceExtensionAbility(want,connect); } // The first parameter specifies the bundle name of the application, and the second parameter specifies the callback used to return the device ID obtained by using DeviceManager. - deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback) + deviceManager.createDeviceManager("ohos.rpc.test", deviceManagerCallback); ``` - 3. Process requests sent from the client. @@ -240,77 +278,79 @@ Table 1 Native IPC APIs ```ts onConnect(want: Want) { - var robj:rpc.RemoteObject = new Stub("rpcTestAbility") - return robj + var robj:rpc.RemoteObject = new Stub("rpcTestAbility"); + return robj; } class Stub extends rpc.RemoteObject { constructor(descriptor) { - super(descriptor) + super(descriptor); } onRemoteMessageRequest(code, data, reply, option) { // Process requests sent from the client based on the code. - return true + return true; } } ``` - - 4. Process responses sent from the server. - Obtain the proxy object from the **onConnect** callback, call **sendRequestAsync** to send a request, and receive the response using a callback or a promise (an object representing the eventual completion or failure of an asynchronous operation and its result value). + Obtain the proxy object from the **onConnect** callback, call **sendRequest** to send a request, and receive the response using a callback or a promise (an object representing the eventual completion or failure of an asynchronous operation and its result value). ```ts // Use a promise. - let option = new rpc.MessageOption() - let data = rpc.MessageParcel.create() - let reply = rpc.MessageParcel.create() + let option = new rpc.MessageOption(); + let data = rpc.MessageParcel.create(); + let reply = rpc.MessageParcel.create(); // Write parameters to data. - proxy.sendRequestAsync(1, data, reply, option) + proxy.sendRequest(1, data, reply, option) .then(function(result) { if (result.errCode != 0) { - console.error("send request failed, errCode: " + result.errCode) - return + console.error("send request failed, errCode: " + result.errCode); + return; } // Read the result from result.reply. }) .catch(function(e) { - console.error("send request got exception: " + e) - } + console.error("send request got exception: " + e); + }) .finally(() => { - data.reclaim() - reply.reclaim() + data.reclaim(); + reply.reclaim(); }) - + // Use a callback. function sendRequestCallback(result) { try { if (result.errCode != 0) { - console.error("send request failed, errCode: " + result.errCode) - return + console.error("send request failed, errCode: " + result.errCode); + return; } // Read the result from result.reply. } finally { - result.data.reclaim() - result.reply.reclaim() + result.data.reclaim(); + result.reply.reclaim(); } } - let option = new rpc.MessageOption() - let data = rpc.MessageParcel.create() - let reply = rpc.MessageParcel.create() + let option = new rpc.MessageOption(); + let data = rpc.MessageParcel.create(); + let reply = rpc.MessageParcel.create(); // Write parameters to data. - proxy.sendRequest(1, data, reply, option, sendRequestCallback) + proxy.sendRequest(1, data, reply, option, sendRequestCallback); ``` 5. Tear down the connection. - Use the API provided by **featureAbility** to tear down the connection when the communication is over. + If you use the FA model, call the API provided by **featureAbility** to tear down the connection when the communication is over. If you use the stage model, obtain a service instance through **Context**, and then call the API provided by **featureAbility** to tear down the connection. ```ts - import rpc from "@ohos.rpc" - import featureAbility from "@ohos.ability.featureAbility" + import rpc from "@ohos.rpc"; + // Import @ohos.ability.featureAbility only for the application developed based on the FA model. + // import featureAbility from "@ohos.ability.featureAbility"; function disconnectCallback() { - console.info("disconnect ability done") + console.info("disconnect ability done"); } - featureAbility.disconnectAbility(connectId, disconnectCallback) + // Use this method to disconnect from the ability in the FA model. + // featureAbility.disconnectAbility(connectId, disconnectCallback); + + globalThis.context.disconnectServiceExtensionAbility(connectId); ``` diff --git a/en/application-dev/connectivity/ipc-rpc-overview.md b/en/application-dev/connectivity/ipc-rpc-overview.md index 29fdec791c9a6b96d2ae2138b47a9b8dc48c050b..995071ebf893e33240019fd35ee1bff30506f151 100755 --- a/en/application-dev/connectivity/ipc-rpc-overview.md +++ b/en/application-dev/connectivity/ipc-rpc-overview.md @@ -3,42 +3,25 @@ ## Basic Concepts -The inter-process communication (IPC) and remote procedure call (RPC) mechanisms are used to implement cross-process communication. The difference between them lies in that IPC uses the Binder driver to implement cross-process communication within a device, whereas RPC uses the DSoftBus driver to implement cross-process communication across devices. +The inter-process communication (IPC) and remote procedure call (RPC) mechanisms are used to implement cross-process communication. The difference between them lies in that IPC uses the Binder driver to implement cross-process communication within a device, whereas RPC uses the DSoftBus driver to implement cross-process communication across devices. The reason why cross-process communication is needed is that each process has its own independent resources and memory space and one process is not allowed to access the resources and memory space of other processes. -The reason why cross-process communication is needed is that each process has its own independent resources and memory space and one process is not allowed to access the resources and memory space of other processes. IPC and RPC usually use the client-server model, where the client (service requester, that is, the process that requests a service) obtains the proxy of the server (service provider, that is, the process that provides the service) and uses the proxy to read and write data to implement data communication across processes. More specifically, the client constructs a proxy object of the server. The proxy object has the same functions as the server. To access a certain API of the server, you only need to access the corresponding API in the proxy object. The proxy object sends the request to the server, and the server processes the received request and returns the processing result to the proxy object through the driver. Then, the proxy object forwards the processing result to the client. The server registers system abilities (SAs) with the system ability manager (SAMgr), which manages the SAs and provides APIs for clients. To communicate with a specific SA, the client must obtain the proxy of the SA from SAMgr. +> **NOTE** +> The applications in the stage model cannot use IPC or RPC directly, and must use the following capabilities to implement related service scenarios: +>- [Background services](../application-models/background-services.md): use IPC to implement service invocation across processes. +>- [Multi-device collaboration](../application-models/hop-multi-device-collaboration.md): uses RPC to call remote interfaces and transfer data. -In the following sections, proxy represents the service requester, and stub represents the service provider. -![IPC&RPC communication mechanisms](figures/IPC_RPC_communication.PNG) +## Implementation Principles +IPC and RPC usually use the client-server model, where the client (service requester, that is, the process that requests a service) obtains the proxy of the server (service provider, that is, the process that provides the service) and uses the proxy to read and write data to implement data communication across processes. More specifically, the client constructs a proxy object of the server. The proxy object has the same functions as the server. To access a certain API of the server, you only need to access the corresponding API in the proxy object. The proxy object sends the request to the server, and the server processes the received request and returns the processing result to the proxy object through the driver. Then, the proxy object forwards the processing result to the client. The server registers system abilities (SAs) with the system ability manager (SAMgr), which manages the SAs and provides APIs for clients. To communicate with a specific SA, the client must obtain the proxy of the SA from SAMgr. In the following sections, proxy represents the service requester, and stub represents the service provider. -## Constraints - -- During cross-process communication within a single device, the maximum amount of data to be transmitted is about 1 MB. If the amount of data to be transmitted exceeds this limit, use the [anonymous shared memory](https://gitee.com/openharmony/docs/blob/master/en/application-dev/reference/apis/js-apis-rpc.md#ashmem8). -- Subscription to death notifications of anonymous stub objects (not registered with SAMgr) is prohibited in RPC. -- During cross-process communication across processes, a proxy object cannot be passed back to the device that hosts the stub object pointed by the proxy object. That is, the proxy object pointing to the stub object of the remote device cannot be passed across processes twice on the local device. - -## **Recommendations** - -First, compile an API class and define message codes in the API class for both communication parties to identify operations. Unimplemented APIs are allowed in the API class because it must be inherited by both communication parties and its inheritance classes cannot be abstract classes. When inheriting the API class, both communication parties must implement the unimplemented APIs, so as to make sure that the inheritance classes are not abstract classes. - -Then, implement the API class specific to the stub, and override the **AsObject** and **OnRemoteRequest** APIs. In addition, compile the proxy to implement the APIs in the API class and override the **AsObject** API. You can also encapsulate an additional API for calling **SendRequest** to send data to the peer. - -After the preceding operations are done, register a system ability (SA) with SAMgr. Note that the registration should be completed in the process that hosts the stub. Then, obtain the proxy from SAMgr as needed to implement cross-process communication with the stub. +![IPC & RPC communication mechanisms] (figures/IPC_RPC_communication.PNG) -Related steps are as follows: -- Implementing the API class: Inherit **IRemoteBroker**, define message codes, and declare APIs that are not implemented in the API class. - -- Implementing the service provider (stub): Inherit **IRemoteStub** or **RemoteObject**, and override the **AsObject** and **OnRemoteRequest** APIs. - -- Implementing the service requester (proxy): Inherit **IRemoteProxy** or **RemoteProxy**, override the **AsObject** API, and encapsulate the required API to call **SendRequest**. - -- Registering the SA: Apply for a unique ID for the SA, and register the SA with SAMgr. - -- Obtaining the SA: Obtain the proxy based on the SA ID and device ID, and use the proxy to communicate with the remote end. +## Constraints +- A maximum of 1 MB data can be transferred in cross-process communication on a single device. If the amount of data to be transmitted is larger than 1 MB, use [anonymous shared memory](../reference/apis/js-apis-rpc.md#ashmem8). -## Related Modules +- Subscription to death notifications of anonymous stub objects (not registered with SAMgr) is prohibited in RPC. -[Distributed Ability Manager Service Framework](https://gitee.com/openharmony/ability_dmsfwk) +- During cross-process communication across processes, a proxy object cannot be passed back to the device that hosts the stub object pointed by the proxy object. That is, the proxy object pointing to the stub object of the remote device cannot be passed across processes twice on the local device. diff --git a/en/application-dev/connectivity/subscribe-remote-state.md b/en/application-dev/connectivity/subscribe-remote-state.md index 4168d4645a8dd122eaf331017a91da0d8ecc2594..5b21750ba8b56fefcb10a5fff653d7512765c279 100755 --- a/en/application-dev/connectivity/subscribe-remote-state.md +++ b/en/application-dev/connectivity/subscribe-remote-state.md @@ -7,7 +7,7 @@ IPC/RPC allows you to subscribe to the state changes of a remote stub object. Wh This subscription mechanism is applicable when the local proxy object needs to detect death of the process hosting the remote stub object or network detach of the device hosting the remote stub object. When the proxy detects death of the remote stub object, the proxy can clear local resources. Currently, IPC supports death notification for anonymous objects, but RPC does not. That is, you can only subscribe to death notifications of services that have been registered with SAMgr. -## **Using Native APIs** +## **Development Using Native APIs** | API| Return Value Type| Feature Description| | -------- | -------- | -------- | @@ -21,7 +21,6 @@ This subscription mechanism is applicable when the local proxy object needs to d #include "iremote_broker.h" #include "iremote_stub.h" - // Define message codes. enum { TRANS_ID_PING_ABILITY = 5, @@ -61,9 +60,6 @@ int TestServiceProxy::TestPingAbility(const std::u16string &dummy){ } ``` - - - ```c++ #include "iremote_object.h" @@ -84,18 +80,54 @@ bool result = object->AddDeathRecipient(deathRecipient); // Add a recipient for result = object->RemoveDeathRecipient(deathRecipient); // Remove the recipient for death notifications. ``` -## **Using JS APIs** +## **Development Using JS APIs** + +| API | Return Value Type| Feature Description | +| ------------------------ | ---------- | ----------------------------------------------------------------- | +| registerDeathRecipient | void | Adds a recipient for death notifications of the remote object, including death notifications of the remote proxy.| +| unregisterDeathRecipient | void | Removes the recipient for death notifications of the remote object. | +| onRemoteDied | void | Called to perform subsequent operations when a death notification of the remote object is received. | + +### Obtaining the Context -| API | Return Value Type| Feature Description | -| -------------------- | ---------- | ------------------------------------------------------------ | -| addDeathRecippient | boolean | Adds a recipient for death notifications of the remote object, including death notifications of the remote proxy.| -| removeDeathRecipient | boolean | Removes the recipient for death notifications of the remote object. | -| onRemoteDied | void | Called to perform subsequent operations when a death notification of the remote object is received.| +If you use the stage model, you need to obtain the context before connecting to an ability. + +```ts +import Ability from "@ohos.app.ability.UIAbility"; + +export default class MainAbility extends Ability { + onCreate(want, launchParam) { + console.log("[Demo] MainAbility onCreate"); + globalThis.context = this.context; + } + onDestroy() { + console.log("[Demo] MainAbility onDestroy"); + } + onWindowStageCreate(windowStage) { + // Main window is created, set main page for this ability + console.log("[Demo] MainAbility onWindowStageCreate"); + } + onWindowStageDestroy() { + // Main window is destroyed, release UI related resources + console.log("[Demo] MainAbility onWindowStageDestroy"); + } + onForeground() { + // Ability has brought to foreground + console.log("[Demo] MainAbility onForeground"); + } + onBackground() { + // Ability has back to background + console.log("[Demo] MainAbility onBackground"); + } +} +``` ### Sample Code ```ts -import FA from "@ohos.ability.featureAbility"; +// Import @ohos.ability.featureAbility only for the application developed based on the FA model. +// import FA from "@ohos.ability.featureAbility"; + let proxy; let connect = { onConnect: function(elementName, remoteProxy) { @@ -113,31 +145,35 @@ let want = { "bundleName": "com.ohos.server", "abilityName": "com.ohos.server.EntryAbility", }; -FA.connectAbility(want, connect); +// Use this method to connect to the ability in the FA model. +// FA.connectAbility(want, connect); + +globalThis.context.connectServiceExtensionAbility(want, connect); + class MyDeathRecipient { onRemoteDied() { console.log("server died"); } } let deathRecipient = new MyDeathRecipient(); -proxy.addDeathRecippient(deathRecipient, 0); -proxy.removeDeathRecipient(deathRecipient, 0); +proxy.registerDeathRecippient(deathRecipient, 0); +proxy.unregisterDeathRecipient(deathRecipient, 0); ``` ## Reverse Death Notification (Anonymous Stub) -Forward dead notification is a mechanism that allows the proxy to detect death notifications of the stub. To achieve reverse dead notification, we can leverage the forward dead notification mechanism to allow the stub to detect death notifications of the proxy. +Forward dead notification is a mechanism that allows the proxy to detect death notifications of the stub. To achieve reverse dead notification, we can leverage the forward dead notification mechanism to allow the stub to detect death notifications of the proxy. Suppose there are two processes, A (the process hosting the original stub) and B (the process hosting the original proxy). After obtaining the proxy object of process A, process B creates an anonymous stub object (that is, a stub object not registered with SAMgr), which can be called a callback stub. Then, process B calls **SendRequest** to send the callback stub to the original stub of process A. As a result, process A obtains the callback proxy of process B. When process B dies or the device hosting process B detaches from the network, the callback stub dies. The callback proxy detects the death of the callback stub and sends a death notification to the original stub. In this way, reverse death notification is implemented. + +Note: -Suppose there are two processes, A (the process hosting the original stub) and B (the process hosting the original proxy). After obtaining the proxy object of process A, process B creates an anonymous stub object (that is, a stub object not registered with SAMgr), which can be called a callback stub. Then, process B calls **SendRequest** to send the callback stub to the original stub of process A. As a result, process A obtains the callback proxy of process B. When process B dies or the device hosting process B detaches from the network, the callback stub dies. The callback proxy detects the death of the callback stub and sends a death notification to the original stub. In this way, reverse death notification is implemented. +> Reverse death notification can only be used for cross-process communication within a device. -> NOTE -> - Reverse death notification can only be used for cross-process communication within a device. -> - When an anonymous stub object is not pointed by any proxy, the kernel automatically reclaims the object. +> When an anonymous stub object is not pointed by any proxy, the kernel automatically reclaims the object. ### Sample Code ```c++ -// Proxy +//Proxy int TestAbilityProxy::TestAnonymousStub() { MessageOption option; @@ -149,7 +185,7 @@ int TestAbilityProxy::TestAnonymousStub() return result; } -// Stub +//Stub int TestAbilityStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParcel &reply, MessageOption &option) { diff --git a/en/application-dev/faqs/faqs-network-management.md b/en/application-dev/faqs/faqs-network-management.md index dd585f87cc40f2942404cc51c3fcb15bcf04d55e..22ec02cb6f3ec1cfa92153d63eba5c01a0740f7c 100644 --- a/en/application-dev/faqs/faqs-network-management.md +++ b/en/application-dev/faqs/faqs-network-management.md @@ -6,7 +6,7 @@ Applicable to: OpenHarmony 3.2 Beta (API version 9) **Solution** -**extraData** indicates additional data in an HTTP request. It varies depending on the HTTP request method. +**extraData** specifies additional data in an HTTP request. It varies depending on the HTTP request method. - If the HTTP request uses a POST or PUT method, **extraData** serves as the content of the HTTP request. - If the HTTP request uses a GET, OPTIONS, DELETE, TRACE, or CONNECT method, **extraData** serves as a supplement to the HTTP request parameters and will be added to the URL when the request is sent. diff --git a/en/application-dev/reference/apis/js-apis-hidebug.md b/en/application-dev/reference/apis/js-apis-hidebug.md index cbd24a590073b4365591a22f0f68332b206805fb..2c9ec4fb91407514f3f27bbc8663c1ab8f282b21 100644 --- a/en/application-dev/reference/apis/js-apis-hidebug.md +++ b/en/application-dev/reference/apis/js-apis-hidebug.md @@ -184,18 +184,18 @@ import featureAbility from '@ohos.ability.featureAbility' let context = featureAbility.getContext(); context.getFilesDir().then((data) => { - var path = data + "/serviceInfo.txt" - console.info("output path: " + path) - let fd = fs.openSync(path, 0o102, 0o666) - var serviceId = 10 - var args = new Array("allInfo") + var path = data + "/serviceInfo.txt"; + console.info("output path: " + path); + let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE); + var serviceId = 10; + var args = new Array("allInfo"); try { - hidebug.getServiceDump(serviceId, fd, args) + hidebug.getServiceDump(serviceId, file.fd, args); } catch (error) { - console.info(error.code) - console.info(error.message) + console.info(error.code); + console.info(error.message); } - fs.closeSync(fd); + fs.closeSync(file); }) ``` diff --git a/en/application-dev/reference/apis/js-apis-logs.md b/en/application-dev/reference/apis/js-apis-logs.md index 673a24f3340de67ad98a86a8b2648e0e9af1693c..c3295f774e6026a4fa79bed3c29255973fc7ac6e 100644 --- a/en/application-dev/reference/apis/js-apis-logs.md +++ b/en/application-dev/reference/apis/js-apis-logs.md @@ -12,6 +12,8 @@ debug(message: string, ...arguments: any[]): void Prints debugging information in formatted output mode. +Since API version 9, this API is supported in ArkTS widgets. + **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** @@ -39,6 +41,8 @@ log(message: string, ...arguments: any[]): void Prints log information in formatted output mode. +Since API version 9, this API is supported in ArkTS widgets. + **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** @@ -66,6 +70,8 @@ info(message: string, ...arguments: any[]): void Prints log information in formatted output mode. This API is the alias of **console.log ()**. +Since API version 9, this API is supported in ArkTS widgets. + **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** @@ -93,6 +99,8 @@ warn(message: string, ...arguments: any[]): void Prints warning information in formatted output mode. +Since API version 9, this API is supported in ArkTS widgets. + **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters** @@ -120,6 +128,8 @@ error(message: string, ...arguments: any[]): void Prints error information in formatted output mode. +Since API version 9, this API is supported in ArkTS widgets. + **System capability**: SystemCapability.ArkUI.ArkUI.Full **Parameters**