提交 07c451db 编写于 作者: 张悦诶

IssueNo:#I574PZ:new HarmonyAppProvison configuration file

Description:new HarmonyAppProvision configuration file
Sig:SIG_ApplicaitonFramework
Feature or Bugfix:Feature
Binary Source:No
......@@ -16,6 +16,6 @@
zh-cn/device-dev/kernel/ @Austin23
zh-cn/device-dev/website.md @Austin23
README.md @Austin23
zh-cn/device-dev/porting duangavin123_admin
zh-cn/device-dev/guide duangavin123_admin
zh-cn/device-dev/subsystems li-yan339
\ No newline at end of file
zh-cn/device-dev/porting/ @duangavin123_admin
zh-cn/device-dev/guide/ @duangavin123_admin
zh-cn/device-dev/subsystems/ @li-yan339
\ No newline at end of file
......@@ -10,33 +10,39 @@
- [Preparations](start-overview.md)
- [Getting Started with eTS in the Traditional Coding Approach](quick-start/start-with-ets.md)
- [Getting Started with eTS in the Low-Code Approach](quick-start/start-with-ets-low-code.md)
- [Getting Started with JavaScript in the Traditional Coding Approach](start-with-js.md)
- [Getting Started with JavaScript in the Low-Code Approach](start-with-js-low-code.md)
- [Getting Started with JavaScript in the Traditional Coding Approach](quick-start/start-with-js.md)
- [Getting Started with JavaScript in the Low-Code Approach](quick-start/start-with-js-low-code.md)
- Development Fundamentals
- [Application Development Package Structure (FA Model)](package-structure.md)
- [Application Development Package Structure (Stage Model)](module-structure.md)
- [Resource File Categories](basic-resource-file-categories.md)
- [SysCap](syscap.md)
- [Application Development Package Structure (FA Model)](quick-start/package-structure.md)
- [Application Development Package Structure (Stage Model)](quick-start/module-structure.md)
- [Resource File Categories](quick-start/basic-resource-file-categories.md)
- [SysCap](quick-start/syscap.md)
- Development
- [Ability Development](ability/Readme-EN.md)
- [UI Development](ui/Readme-EN.md)
- Basic Feature Development
- [Common Event and Notification](notification/Readme-EN.md)
- [Window Manager](windowmanager/Readme-EN.md)
- [WebGL](webgl/Readme-EN.md)
- [Media](media/Readme-EN.md)
- [Security](security/Readme-EN.md)
- [Connectivity](connectivity/Readme-EN.md)
- [Data Management](database/Readme-EN.md)
- [Telephony](telephony/Readme-EN.md)
- [Agent-Powered Scheduled Reminders](background-agent-scheduled-reminder/Readme-EN.md)
- [Background Task Management](background-task-management/Readme-EN.md)
- [Work Scheduler](work-scheduler/Readme-EN.md)
- [Device Management](device/Readme-EN.md)
- [Device Usage Statistics](device-usage-statistics/Readme-EN.md)
- [DFX](dfx/Readme-EN.md)
- [Internationalization](internationalization/Readme-EN.md)
-
- [Using Native APIs in Application Projects](napi/napi-guidelines.md)
- Tools
- [DevEco Studio (OpenHarmony) User Guide](quick-start/deveco-studio-user-guide-for-openharmony.md)
- Hands-On Tutorials
- [Samples](https://gitee.com/openharmony/app_samples/blob/master/README.md)
- [Codelabs](https://gitee.com/openharmony/codelabs)
- API References
- [Component Reference (JavaScript-based Web-like Development Paradigm)](reference/arkui-js/Readme-EN.md)
- [Component Reference (TypeScript-based Declarative Development Paradigm)](reference/arkui-ts/Readme-EN.md)
......
# Ability Development
- [Ability Framework Overview](ability-brief.md)
- FA Model
- [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
- [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
- Other
- [WantAgent Development](wantagent.md)
- [Ability Assistant Usage](ability-assistant-guidelines.md)
- [Test Framework Usage](ability-delegator.md)
......
# Context Usage
## Context Overview
**context** provides the capability of obtaining contextual information of an application.
## Context Structure
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, which does not belong to either model. It has only one attribute, **stageMode**, which specifies whether the context is used for the stage model.
The FA model has only one type of context: **app/Context**. 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.
The stage model has six types of contexts: **application/Context**, **application/AbilityStageContext**, **application/ExtensionContext**, **application/AbilityContext**, **application/FormExtensionContext**, and **application/ServiceExtensionContext**. 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.
The context is defined in the d.ts file below:
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/app/context.d.ts
Use the context as follows:
```javascript
// 1. Import featureAbility.
import featureAbility from '@ohos.ability.featureAbility'
export default {
onCreate() {
console.log('Application onCreate')
// 2. Obtain the context.
let context = featureAbility.getContext();
// 3. Call the methods.
context.setShowOnLockScreen(false, (data) => {
console.log("data: " + JSON.stringify(data));
});
},
onActive() {
console.log('Application onActive')
},
onDestroy() {
console.log('Application onDestroy')
},
}
```
## Context in the Stage Model
The stage model has six contexts. The following describes these contexts in detail.
### application/Context
**Overview**
**application/Context** is the base class context that provides basic application information such as **resourceManager**, **applicationInfo**, and **cacheDir**. It also provides basic application methods such as **createBundleContext** and **switchArea**. The application-level context is of the **application/Context** type.
**How to Obtain**
Obtain the context by calling **context.getApplicationContext()** in **AbilityStage**, **Ability**, and **Extension**.
**Example**
```javascript
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log('MainAbility onCreate is called' + want + launchParam);
// Obtain the application context.
let appContext = this.context.getApplicationContext();
// Obtain the path.
console.log('filesDir is ' + appContext.filesDir);
}
onDestroy() {
console.log('MainAbility onDestroy is called');
}
}
```
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/Context.d.ts
### application/AbilityStageContext
**Overview**
**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 ' + context.currentHapModuleInfo);
}
}
```
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityStageContext.d.ts
### application/AbilityContext
**Overview**
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
export default class MainAbility extends Ability {
onCreate(want, launchParam) {
console.log('MainAbility onCreate is called' + want + launchParam);
var want = {
"bundleName": "com.example.MyApplication",
"abilityName": "ServiceExtAbility",
}
// 1. The context here is of the AbilityContext type.
let contxt = this.context;
// 2. Start the ability.
contxt.startAbility(want).then((data) => {
console.info("startAbility success:" + JSON.stringify(data));
}).catch((error) => {
console.error("startAbility failed:" + JSON.stringify(error));
});
}
onDestroy() {
console.log("MainAbility on Destroy is called");
}
}
```
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/AbilityContext.d.ts
### application/ExtensionContext
**Overview**
Unlike the FA model, the stage model separates **Service** from **Ability** and defines a group of **Extension** classes to provide the same capabilities. **Extension** is a base class and does not provide specific service functions. The service party extends the corresponding **Extension** class as required. For example, a Service ability is extended to **ServiceExtensionAbility**, and a form (service widget) is extended to **FormExtensionAbility**.
**ExtensionContext** provides the context for the extension. **ExtensionContext** has the **HapModuleInfo** and **Configuration** attributes.
**How to Obtain**
This type of context is not used independently.
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ExtensionContext.d.ts
### application/ServiceExtensionContext
**Overview**
Similar to **ServiceAbility** of the FA model, **ServiceExtensionAbility** contains only the processing related to lifecycle callbacks.
The methods for operating the Service Extension ability (such as **startAbility** and **connectAbility**) are provided in **ServiceExtensionContext**.
**How to Obtain**
Obtain the context from the **context** attribute in **ServiceExtensionAbility**.
**Example**
```javascript
export default class ServiceExtAbility extends ServiceExtensionAbility {
onCreate(want) {
console.info("ServiceAbility onCreate**");
// The context here is of the ServiceExtensionContext type.
let contxt = this.context;
}
onRequest(want, startId) {
console.info("ServiceAbility onRequest**");
}
onConnect(want) {
console.info("ServiceAbility onConnect**");
return new StubTest("test");
}
onDisconnect(want) {
console.info("ServiceAbility onDisconnect**");
}
onDestroy() {
console.info("ServiceAbility onDestroy**");
}
}
```
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/ServiceExtensionContext.d.ts
### application/FormExtensionContext
For details, see [FormExtensionContext](/en/application-dev/reference/apis/js-apis-formextensioncontext.md)
**d.ts statement**
https://gitee.com/openharmony/interface_sdk-js/blob/master/api/application/FormExtensionContext.d.ts
## FAQs
Can I obtain the context through globalThis?
**Answer**
You can use **globalThis** to obtain the context in the FA model, but not in the stage model. To obtain the context in the stage model, use the **context** attribute in the corresponding component.
**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.
......@@ -22,32 +22,43 @@ For details about the APIs, see [AudioPlayer in the Media API](../reference/apis
The full audio playback process includes creating an instance, setting the URI, playing audio, seeking to the playback position, setting the volume, pausing playback, obtaining track information, stopping playback, resetting the player, and releasing resources.
For details about the **src** media source input types supported by **AudioPlayer**, see the [src attribute](../reference/apis/js-apis-media.md#audioplayer_attributes).
For details about the **src** types supported by **AudioPlayer**, see the [src attribute](../reference/apis/js-apis-media.md#audioplayer_attributes).
```js
import media from '@ohos.multimedia.media'
import fileIO from '@ohos.fileio'
function SetCallBack(audioPlayer) {
// Print the stream track information.
function printfDescription(obj) {
for (let item in obj) {
let property = obj[item];
console.info('audio key is ' + item);
console.info('audio value is ' + property);
}
}
// Set the player callbacks.
function setCallBack(audioPlayer) {
audioPlayer.on('dataLoad', () => { // Set the 'dataLoad' event callback, which is triggered when the src attribute is set successfully.
console.info('audio set source success');
// The playback page is ready. You can click the Play button to start the playback.
audioPlayer.play(); // The play() API can be invoked only after the 'dataLoad' event callback is complete. The 'play' event callback is then triggered.
});
audioPlayer.on('play', () => { // Set the 'play' event callback.
console.info('audio play success');
// The Play button is changed to the pausable state.
audioPlayer.pause(); // Trigger the 'pause' event callback and pause the playback.
});
audioPlayer.on('pause', () => { // Set the 'pause' event callback.
console.info('audio pause success');
// The Play button is changed to the playable state.
audioPlayer.seek(5000); // Trigger the 'timeUpdate' event callback, and seek to 5000 ms for playback.
});
audioPlayer.on('stop', () => { // Set the 'stop' event callback.
console.info('audio stop success');
// The playback stops, the playback progress bar returns to 0, and the Play button is changed to the playable state.
audioPlayer.reset(); // Trigger the 'reset' event callback, and reconfigure the src attribute to switch to the next song.
});
audioPlayer.on('reset', () => { // Set the 'reset' event callback.
console.info('audio reset success');
// You can reconfigure the src attribute to play another audio file.
audioPlayer.release(); // Release the AudioPlayer resources.
audioPlayer = undefined;
});
audioPlayer.on('timeUpdate', (seekDoneTime) => {// Set the 'timeUpdate' event callback.
if (typeof(seekDoneTime) == 'undefined') {
......@@ -55,11 +66,20 @@ function SetCallBack(audioPlayer) {
return;
}
console.info('audio seek success, and seek time is ' + seekDoneTime);
// The playback progress bar is updated to the seek position.
audioPlayer.setVolume(0.5); // Trigger the 'volumeChange' event callback.
});
audioPlayer.on('volumeChange', () => { // Set the 'volumeChange' event callback.
console.info('audio volumeChange success');
// Display the updated volume.
audioPlayer.getTrackDescription((error, arrlist) => { // Obtain the audio track information in callback mode.
if (typeof (arrlist) != 'undefined') {
for (let i = 0; i < arrlist.length; i++) {
printfDescription(arrlist[i]);
}
} else {
console.log(`audio getTrackDescription fail, error:${error.message}`);
}
audioPlayer.stop(); // Trigger the 'stop' event callback to stop the playback.
});
});
audioPlayer.on('finish', () => { // Set the 'finish' event callback, which is triggered when the playback is complete.
console.info('audio play finish');
......@@ -71,56 +91,24 @@ function SetCallBack(audioPlayer) {
});
}
function printfDescription(obj) {
for (let item in obj) {
let property = obj[item];
console.info('audio key is ' + item);
console.info('audio value is ' + property);
}
}
// 1. Create an audioPlayer instance.
let audioPlayer = media.createAudioPlayer();
SetCallBack(audioPlayer); // Set the event callbacks.
// 2. Set the URI of the audio file selected by the user.
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" command.
let path = '/data/accounts/account_0/appdata/ohos.xxx.xxx.xxx/01.mp3';
await fileIO.open(path).then(fdNumber) => {
async function audioPlayerDemo() {
// 1. Create an audioPlayer instance.
let audioPlayer = media.createAudioPlayer();
setCallBack(audioPlayer); // Set the event callbacks.
// 2. Set the URI of the audio file selected by the user.
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile" command.
let path = '/data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile/01.mp3';
await fileIO.open(path).then((fdNumber) => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, (err) => {
}, (err) => {
console.info('open fd failed err is' + err);
}),catch((err) => {
}).catch((err) => {
console.info('open fd failed err is' + err);
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
// 3. Play the audio file.
audioPlayer.play(); // The play() API can be invoked only after the 'dataLoad' event callback is complete. The 'play' event callback is triggered.
// 4. Seek to the playback position.
audioPlayer.seek(30000); // Trigger the 'timeUpdate' event callback, and seek to 30000 ms for playback.
// 5. Set the volume.
audioPlayer.setVolume(0.5); // Trigger the 'volumeChange' event callback.
// 6. Pause the playback.
audioPlayer.pause(); // Trigger the 'pause' event callback and pause the playback.
// 7. Obtain the track information.
audioPlayer.getTrackDescription((error, arrlist) => { // Obtain the audio track information in callback mode.
if (typeof (arrlist) != 'undefined') {
for (let i = 0; i < arrlist.length; i++) {
printfDescription(arrlist[i]);
}
} else {
console.log(`audio getTrackDescription fail, error:${error.message}`);
}
});
// 8. Stop the playback.
audioPlayer.stop(); // Trigger the 'stop' event callback.
// 9. Reset the player.
audioPlayer.reset(); // Trigger the 'reset' event callback, and reconfigure the src attribute to switch to the next song.
// 10. Release the resource.
audioPlayer.release(); // Release the AudioPlayer instance.
audioPlayer = undefined;
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
}
```
### Normal Playback Scenario
......@@ -128,8 +116,9 @@ audioPlayer = undefined;
```js
import media from '@ohos.multimedia.media'
import fileIO from '@ohos.fileio'
function SetCallBack(audioPlayer) {
export class AudioDemo {
// Set the player callbacks.
setCallBack(audioPlayer) {
audioPlayer.on('dataLoad', () => { // Set the 'dataLoad' event callback, which is triggered when the src attribute is set successfully.
console.info('audio set source success');
audioPlayer.play(); // Call the play() API to start the playback and trigger the 'play' event callback.
......@@ -139,27 +128,28 @@ function SetCallBack(audioPlayer) {
});
audioPlayer.on('finish', () => { // Set the 'finish' event callback, which is triggered when the playback is complete.
console.info('audio play finish');
audioPlayer.release(); // Release the AudioPlayer instance.
audioPlayer.release(); // Release the AudioPlayer resources.
audioPlayer = undefined;
});
}
}
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
SetCallBack(audioPlayer); // Set the event callbacks.
/* Set the FD (local playback) of the audio file selected by the user. */
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" command.
let path = '/data/accounts/account_0/appdata/ohos.xxx.xxx.xxx/01.mp3';
await fileIO.open(path).then(fdNumber) => {
async audioPlayerDemo() {
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
this.setCallBack(audioPlayer); // Set the event callbacks.
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile" command.
let path = '/data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile/01.mp3';
await fileIO.open(path).then((fdNumber) => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, (err) => {
}, (err) => {
console.info('open fd failed err is' + err);
}),catch((err) => {
}).catch((err) => {
console.info('open fd failed err is' + err);
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
}
}
```
### Switching to the Next Song
......@@ -167,54 +157,62 @@ audioPlayer.src = fdPath; // Set the src attribute and
```js
import media from '@ohos.multimedia.media'
import fileIO from '@ohos.fileio'
function SetCallBack(audioPlayer) {
export class AudioDemo {
// Set the player callbacks.
private isNextMusic = false;
setCallBack(audioPlayer) {
audioPlayer.on('dataLoad', () => { // Set the 'dataLoad' event callback, which is triggered when the src attribute is set successfully.
console.info('audio set source success');
audioPlayer.play(); // Call the play() API to start the playback and trigger the 'play' event callback.
});
audioPlayer.on('play', () => { // Set the 'play' event callback.
console.info('audio play success');
audioPlayer.reset(); // Call the reset() API and trigger the 'reset' event callback.
});
audioPlayer.on('finish', () => { // Set the 'finish' event callback, which is triggered when the playback is complete.
console.info('audio play finish');
audioPlayer.on('reset', () => { // Set the 'reset' event callback.
console.info('audio play success');
if (!this.isNextMusic) { // When isNextMusic is false, changing songs is implemented.
this.nextMusic(audioPlayer); // Changing songs is implemented.
} else {
audioPlayer.release(); // Release the AudioPlayer instance.
audioPlayer = undefined;
}
});
}
}
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
SetCallBack(audioPlayer); // Set the event callbacks.
/* Set the FD (local playback) of the audio file selected by the user. */
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" command.
let path = '/data/accounts/account_0/appdata/ohos.xxx.xxx.xxx/01.mp3';
await fileIO.open(path).then(fdNumber) => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, (err) => {
async nextMusic(audioPlayer) {
this.isNextMusic = true;
let nextFdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\02.mp3 /data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile" command.
let nextpath = '/data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile/02.mp3';
await fileIO.open(nextpath).then((fdNumber) => {
nextFdPath = nextFdPath + '' + fdNumber;
console.info('open fd sucess fd is' + nextFdPath);
}, (err) => {
console.info('open fd failed err is' + err);
}),catch((err) => {
}).catch((err) => {
console.info('open fd failed err is' + err);
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
/* Send the instruction to switch to the next song after a period of time. */
audioPlayer.reset();
});
audioPlayer.src = nextFdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
}
/* Set the FD (local playback) of the audio file selected by the user. */
let fdNextPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\02.mp3 /data/accounts/account_0/appdata" command.
let nextPath = '/data/accounts/account_0/appdata/ohos.xxx.xxx.xxx/02.mp3';
await fileIO.open(nextPath).then(fdNumber) => {
fdNextPath = fdNextPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdNextPath);
}, (err) => {
async audioPlayerDemo() {
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
this.setCallBack(audioPlayer); // Set the event callbacks.
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile" command.
let path = '/data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile/01.mp3';
await fileIO.open(path).then((fdNumber) => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, (err) => {
console.info('open fd failed err is' + err);
}),catch((err) => {
}).catch((err) => {
console.info('open fd failed err is' + err);
});
audioPlayer.src = fdNextPath;
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
}
}
```
### Looping a Song
......@@ -222,40 +220,36 @@ audioPlayer.src = fdNextPath;
```js
import media from '@ohos.multimedia.media'
import fileIO from '@ohos.fileio'
function SetCallBack(audioPlayer) {
export class AudioDemo {
// Set the player callbacks.
setCallBack(audioPlayer) {
audioPlayer.on('dataLoad', () => { // Set the 'dataLoad' event callback, which is triggered when the src attribute is set successfully.
console.info('audio set source success');
audioPlayer.loop = true; // Set the loop playback attribute.
audioPlayer.play(); // Call the play() API to start the playback and trigger the 'play' event callback.
});
audioPlayer.on('play', () => { // Set the 'play' event callback.
audioPlayer.on('play', () => { // Sets the 'play' event callback to start loop playback.
console.info('audio play success');
});
audioPlayer.on('finish', () => { // Set the 'finish' event callback, which is triggered when the playback is complete.
console.info('audio play finish');
audioPlayer.release(); // Release the AudioPlayer instance.
audioPlayer = undefined;
});
}
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
SetCallBack(audioPlayer); // Set the event callbacks.
}
/* Set the FD (local playback) of the audio file selected by the user. */
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/accounts/account_0/appdata" command.
let path = 'data/accounts/account_0/appdata/ohos.xxx.xxx.xxx/01.mp3';
await fileIO.open(path).then(fdNumber) => {
async audioPlayerDemo() {
let audioPlayer = media.createAudioPlayer(); // Create an AudioPlayer instance.
this.setCallBack(audioPlayer); // Set the event callbacks.
let fdPath = 'fd://'
// The stream in the path can be pushed to the device by running the "hdc file send D:\xxx\01.mp3 /data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile" command.
let path = '/data/app/el1/bundle/public/ohos.acts.multimedia.audio.audioplayer/ohos.acts.multimedia.audio.audioplayer/assets/entry/resources/rawfile/01.mp3';
await fileIO.open(path).then((fdNumber) => {
fdPath = fdPath + '' + fdNumber;
console.info('open fd sucess fd is' + fdPath);
}, (err) => {
}, (err) => {
console.info('open fd failed err is' + err);
}),catch((err) => {
}).catch((err) => {
console.info('open fd failed err is' + err);
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
audioPlayer.loop = true; // Set the loop playback attribute.
});
audioPlayer.src = fdPath; // Set the src attribute and trigger the 'dataLoad' event callback.
}
}
```
## Samples
......@@ -263,7 +257,6 @@ audioPlayer.loop = true; // Set the loop playback att
The following samples are provided to help you better understand how to develop audio playback:
- [`JsDistributedMusicPlayer`: Distributed Music Player (JS) (API7)](https://gitee.com/openharmony/app_samples/tree/master/ability/JsDistributedMusicPlayer)
- [`JsAudioPlayer`: Audio Playback and Management (JS) (API7)](https://gitee.com/openharmony/app_samples/tree/master/media/JsAudioPlayer)
- [`JsAudioPlayer`: Audio Playback and Management (JS, API 7)](https://gitee.com/openharmony/app_samples/tree/master/media/JsAudioPlayer)
- [`eTsAudioPlayer`: Audio Player (eTS)](https://gitee.com/openharmony/app_samples/blob/master/media/Recorder/entry/src/main/ets/MainAbility/pages/Play.ets)
- [Audio Player](https://gitee.com/openharmony/codelabs/tree/master/Media/Audio_OH_ETS)
......@@ -25,46 +25,49 @@ The full audio recording process includes creating an instance, setting recordin
```js
import media from '@ohos.multimedia.media'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
export class AudioRecorderDemo {
private testFdNumber; // Used to save the FD address.
let testFdNumber;
function SetCallBack(audioRecorder) {
// Set the callbacks related to audio recording.
setCallBack(audioRecorder) {
audioRecorder.on('prepare', () => { // Set the 'prepare' event callback.
console.log('prepare success');
// The recording page is ready. You can click the Record button to start recording.
audioRecorder.start(); // Call the start API to start recording and trigger the 'start' event callback.
});
audioRecorder.on('start', () => { // Set the 'start' event callback.
console.log('audio recorder start success');
// The Record button is changed to the pausable state.
audioRecorder.pause(); // Call the pause API to pause recording and trigger the 'pause' event callback.
});
audioRecorder.on('pause', () => { // Set the 'pause' event callback.
console.log('audio recorder pause success');
// The Record button is changed to the recordable state.
audioRecorder.resume(); // Call the resume API to resume recording and trigger the 'resume' event callback.
});
audioRecorder.on('resume', () => { // Set the 'resume' event callback.
console.log('audio recorder resume success');
// The Record button is changed to the pausable state.
audioRecorder.stop(); // Call the stop API to stop recording and trigger the 'stop' event callback.
});
audioRecorder.on('stop', () => { // Set the 'stop' event callback.
console.log('audio recorder stop success');
});
audioRecorder.on('release', () => { // Set the 'release' event callback.
console.log('audio recorder release success');
audioRecorder.reset(); // Call the reset API to reset the recorder and trigger the 'reset' event callback.
});
audioRecorder.on('reset', () => { // Set the 'reset' event callback.
console.log('audio recorder reset success');
// You need to reset the recording parameters for another recording.
audioRecorder.release(); // Call the release API to release resources and trigger the 'release' event callback.
});
audioRecorder.on('release', () => { // Set the 'release' event callback.
console.log('audio recorder release success');
audioRecorder = undefined;
});
audioRecorder.on('error', (error) => { // Set the 'error' event callback.
console.info(`audio error called, errName is ${error.name}`);
console.info(`audio error called, errCode is ${error.code}`);
console.info(`audio error called, errMessage is ${error.message}`);
});
}
}
// pathName indicates the passed recording file name, for example, 01.mp3. The generated file address is /storage/media/100/local/files/Movies/01.mp3.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async function getFd(pathName) {
// pathName indicates the passed recording file name, for example, 01.mp3. The generated file address is /storage/media/100/local/files/Video/01.mp3.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async getFd(pathName) {
let displayName = pathName;
const mediaTest = mediaLibrary.getMediaLibrary();
let fileKeyObj = mediaLibrary.FileKey;
......@@ -80,41 +83,29 @@ async function getFd(pathName) {
let fetchFileResult = await mediaTest.getFileAssets(fetchOp);
let fileAsset = await fetchFileResult.getAllObject();
let fdNumber = await fileAsset[0].open('Rw');
fdNumber = "fd://" + fdNumber.toString();
testFdNumber = fdNumber;
this.testFdNumber = "fd://" + fdNumber.toString();
}
}
}
await getFd('01.mp3');
// 1. Create an AudioRecorder instance.
let audioRecorder = media.createAudioRecorder();
// 2. Set the callbacks.
SetCallBack(audioRecorder);
// 3. Set the recording parameters.
let audioRecorderConfig = {
audioEncoder : media.AudioEncoder.AAC_LC ,
async audioRecorderDemo() {
// 1. Create an AudioRecorder instance.
let audioRecorder = media.createAudioRecorder();
// 2. Set the callbacks.
this.setCallBack(audioRecorder);
await this.getFd('01.mp3'); // Call the getFd method to obtain the FD address of the file to be recorded.
// 3. Set the recording parameters.
let audioRecorderConfig = {
audioEncodeBitRate : 22050,
audioSampleRate : 22050,
numberOfChannels : 2,
format : media.AudioOutputFormat.AAC_ADTS,
uri : testFdNumber, // testFdNumber is generated by getFd.
uri : this.testFdNumber, // testFdNumber is generated by getFd.
location : { latitude : 30, longitude : 130},
audioEncoderMime : media.CodecMimeType.AUDIO_AAC,
fileFormat : media.ContainerFormatType.CFT_MPEG_4A,
}
audioRecorder.prepare(audioRecorderConfig); // Call the prepare method to trigger the 'prepare' event callback.
}
}
audioRecorder.prepare(audioRecorderConfig);
// 4. Start recording.
audioRecorder.start(); // The start API can be called to trigger the 'start' event callback only after the 'prepare' event callback is complete.
// 5. Pause recording.
audioRecorder.pause(); // The pause API can be called to trigger the 'pause' event callback only after the 'start' event callback is complete.
// 6. Resume recording.
audioRecorder.resume(); // The resume API can be called to trigger the 'resume' event callback only after the 'pause' event callback is complete.
// 7. Stop recording.
audioRecorder.stop(); // The stop API can be called to trigger the 'stop' event callback only after the 'start' or 'resume' event callback is complete.
// 8. Reset recording.
audioRecorder.reset(); // The prepare API can be called for another recording only after the 'reset' event callback is complete.
// 9. Release resources.
audioRecorder.release(); // The AudioRecorder resource is destroyed.
audioRecorder = undefined;
```
### Normal Recording Scenario
......@@ -124,29 +115,37 @@ Unlike the full-process scenario, the normal recording scenario does not include
```js
import media from '@ohos.multimedia.media'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
export class AudioRecorderDemo {
private testFdNumber; // Used to save the FD address.
let testFdNumber;
function SetCallBack(audioRecorder) {
// Set the callbacks related to audio recording.
setCallBack(audioRecorder) {
audioRecorder.on('prepare', () => { // Set the 'prepare' event callback.
console.log('prepare success');
// The recording page is ready. You can click the Record button to start recording.
audioRecorder.start(); // Call the start API to start recording and trigger the 'start' event callback.
});
audioRecorder.on('start', () => { // Set the 'start' event callback.
console.log('audio recorder start success');
// The Record button is changed to the pausable state.
audioRecorder.stop(); // Call the stop API to stop recording and trigger the 'stop' event callback.
});
audioRecorder.on('stop', () => { // Set the 'stop' event callback.
console.log('audio recorder stop success');
audioRecorder.release(); // Call the release API to release resources and trigger the 'release' event callback.
});
audioRecorder.on('release', () => { // Set the 'release' event callback.
console.log('audio recorder release success');
audioRecorder = undefined;
});
}
audioRecorder.on('error', (error) => { // Set the 'error' event callback.
console.info(`audio error called, errName is ${error.name}`);
console.info(`audio error called, errCode is ${error.code}`);
console.info(`audio error called, errMessage is ${error.message}`);
});
}
// pathName indicates the passed recording file name, for example, 01.mp3. The generated file address is /storage/media/100/local/files/Movies/01.mp3.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async function getFd(pathName) {
// pathName indicates the passed recording file name, for example, 01.mp3. The generated file address is /storage/media/100/local/files/Video/01.mp3.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async getFd(pathName) {
let displayName = pathName;
const mediaTest = mediaLibrary.getMediaLibrary();
let fileKeyObj = mediaLibrary.FileKey;
......@@ -162,33 +161,35 @@ async function getFd(pathName) {
let fetchFileResult = await mediaTest.getFileAssets(fetchOp);
let fileAsset = await fetchFileResult.getAllObject();
let fdNumber = await fileAsset[0].open('Rw');
fdNumber = "fd://" + fdNumber.toString();
testFdNumber = fdNumber;
this.testFdNumber = "fd://" + fdNumber.toString();
}
}
}
await getFd('01.mp3');
// 1. Create an AudioRecorder instance.
let audioRecorder = media.createAudioRecorder();
// 2. Set the callbacks.
SetCallBack(audioRecorder);
// 3. Set the recording parameters.
let audioRecorderConfig = {
audioEncoder : media.AudioEncoder.AAC_LC ,
async audioRecorderDemo() {
// 1. Create an AudioRecorder instance.
let audioRecorder = media.createAudioRecorder();
// 2. Set the callbacks.
this.setCallBack(audioRecorder);
await this.getFd('01.mp3'); // Call the getFd method to obtain the FD address of the file to be recorded.
// 3. Set the recording parameters.
let audioRecorderConfig = {
audioEncodeBitRate : 22050,
audioSampleRate : 22050,
numberOfChannels : 2,
format : media.AudioOutputFormat.AAC_ADTS,
uri : testFdNumber, // testFdNumber is generated by getFd.
uri : this.testFdNumber, // testFdNumber is generated by getFd.
location : { latitude : 30, longitude : 130},
audioEncoderMime : media.CodecMimeType.AUDIO_AAC,
fileFormat : media.ContainerFormatType.CFT_MPEG_4A,
}
audioRecorder.prepare(audioRecorderConfig); // Call the prepare method to trigger the 'prepare' event callback.
}
}
audioRecorder.prepare(audioRecorderConfig)
// 4. Start recording.
audioRecorder.start(); // The start API can be called to trigger the 'start' event callback only after the 'prepare' event callback is complete.
// 5. Stop recording.
audioRecorder.stop(); // The stop API can be called to trigger the 'stop' event callback only after the 'start' or 'resume' event callback is complete.
// 6. Release resources.
audioRecorder.release(); // The AudioRecorder resource is destroyed.
audioRecorder = undefined;
```
## Samples
The following samples are provided to help you better understand how to develop audio recording:
- [`Recorder`: Recorder (eTS, API 8)](https://gitee.com/openharmony/app_samples/tree/master/media/Recorder)
- [`eTsAudioPlayer`: Audio Player (eTS)](https://gitee.com/openharmony/app_samples/blob/master/media/Recorder/entry/src/main/ets/MainAbility/pages/Play.ets)
- [Audio Player](https://gitee.com/openharmony/codelabs/tree/master/Media/Audio_OH_ETS)
......@@ -16,21 +16,20 @@ During video recording, audio and video signals are captured, encoded, and saved
## How to Develop
For details about the APIs used for video recording, see [VideoRecorder in the Media API](../reference/apis/js-apis-media.md).
For details about the APIs, see [VideoRecorder in the Media API](../reference/apis/js-apis-media.md).
### Full-Process Scenario
The full video recording process includes creating an instance, setting recording parameters, recording video, pausing, resuming, and stopping recording, and releasing resources.
The full video recording process includes creating an instance, setting recording parameters, starting, pausing, resuming, and stopping recording, and releasing resources.
```js
import media from '@ohos.multimedia.media'
import mediaLibrary from '@ohos.multimedia.mediaLibrary'
let testFdNumber;
// pathName indicates the passed recording file name, for example, 01.mp4. The generated file address is /storage/media/100/local/files/Movies/01.mp4.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async function getFd(pathName) {
export class VideoRecorderDemo {
private testFdNumber; // Used to save the FD address.
// pathName indicates the passed recording file name, for example, 01.mp4. The generated file address is /storage/media/100/local/files/Video/01.mp4.
// To use the media library, declare the following permissions: ohos.permission.MEDIA_LOCATION, ohos.permission.WRITE_MEDIA, and ohos.permission.READ_MEDIA.
async getFd(pathName) {
let displayName = pathName;
const mediaTest = mediaLibrary.getMediaLibrary();
let fileKeyObj = mediaLibrary.FileKey;
......@@ -46,14 +45,31 @@ async function getFd(pathName) {
let fetchFileResult = await mediaTest.getFileAssets(fetchOp);
let fileAsset = await fetchFileResult.getAllObject();
let fdNumber = await fileAsset[0].open('Rw');
fdNumber = "fd://" + fdNumber.toString();
testFdNumber = fdNumber;
this.testFdNumber = "fd://" + fdNumber.toString();
}
}
}
await getFd('01.mp4');
// Error callback triggered in the case of an error
failureCallback(error) {
console.info('error happened, error name is ' + error.name);
console.info('error happened, error code is ' + error.code);
console.info('error happened, error message is ' + error.message);
}
let videoProfile = {
// Error callback triggered in the case of an exception
catchCallback(error) {
console.info('catch error happened, error name is ' + error.name);
console.info('catch error happened, error code is ' + error.code);
console.info('catch error happened, error message is ' + error.message);
}
async videoRecorderDemo() {
let videoRecorder = null; // videoRecorder is an empty object and assigned with a value after createVideoRecorder is successfully called.
let surfaceID = null; // Used to save the surface ID returned by getInputSurface.
// Obtain the FD address of the video to be recorded.
await this.getFd('01.mp4');
// Recording-related parameter settings
let videoProfile = {
audioBitrate : 48000,
audioChannels : 2,
audioCodec : 'audio/mp4a-latm',
......@@ -64,36 +80,18 @@ let videoProfile = {
videoFrameWidth : 640,
videoFrameHeight : 480,
videoFrameRate : 30
}
}
let videoConfig = {
let videoConfig = {
audioSourceType : 1,
videoSourceType : 0,
profile : videoProfile,
url: testFdNumber, // testFdNumber is generated by getFd.
url : this.testFdNumber, // testFdNumber is generated by getFd.
orientationHint : 0,
location : { latitude : 30, longitude : 130 },
}
// Error callback triggered in the case of an error
function failureCallback(error) {
console.info('error happened, error name is ' + error.name);
console.info('error happened, error code is ' + error.code);
console.info('error happened, error message is ' + error.message);
}
// Error callback triggered in the case of an exception
function catchCallback(error) {
console.info('catch error happened, error name is ' + error.name);
console.info('catch error happened, error code is ' + error.code);
console.info('catch error happened, error message is ' + error.message);
}
let videoRecorder = null; // videoRecorder is an empty object and assigned with a value after createVideoRecorder is successfully called.
let surfaceID = null; // Used to save the surface ID returned by getInputSurface.
// Create a VideoRecorder object.
await media.createVideoRecorder().then((recorder) => {
}
// Create a VideoRecorder object.
await media.createVideoRecorder().then((recorder) => {
console.info('case createVideoRecorder called');
if (typeof (recorder) != 'undefined') {
videoRecorder = recorder;
......@@ -101,47 +99,53 @@ await media.createVideoRecorder().then((recorder) => {
} else {
console.info('createVideoRecorder failed');
}
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Obtain the surface ID, save it, and pass it to camera-related interfaces.
await videoRecorder.getInputSurface().then((surface) => {
// Call the prepare API to prepare for video recording.
await videoRecorder.prepare(videoConfig).then(() => {
console.info('prepare success');
}, this.failureCallback).catch(this.catchCallback);
// Obtain the surface ID, save it, and pass it to camera-related APIs.
await videoRecorder.getInputSurface().then((surface) => {
console.info('getInputSurface success');
surfaceID = surface;
}, failureCallback).catch(catchCallback);
// Video recording depends on camera-related interfaces. The following operations can be performed only after the video output start interface is invoked.
}, this.failureCallback).catch(this.catchCallback);
// Start video recording.
await videoRecorder.start().then(() => {
// Video recording depends on camera-related APIs. The following operations can be performed only after the video output start API is invoked. For details about how to call the camera APIs, see the samples.
// Start video recording.
await videoRecorder.start().then(() => {
console.info('start success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Pause video playback before the video output stop interface is invoked.
await videoRecorder.pause().then(() => {
// Pause video recording before the video output stop API of the camera is invoked.
await videoRecorder.pause().then(() => {
console.info('pause success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Resume video playback after the video output start interface is invoked.
await videoRecorder.resume().then(() => {
// Resume video recording after the video output start API of the camera is invoked.
await videoRecorder.resume().then(() => {
console.info('resume success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Stop video recording after the video output stop interface is invoked.
await videoRecorder.stop().then(() => {
// Stop video recording after the video output stop API of the camera is invoked.
await videoRecorder.stop().then(() => {
console.info('stop success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Reset the recording configuration.
await videoRecorder.reset().then(() => {
// Reset the recording configuration.
await videoRecorder.reset().then(() => {
console.info('reset success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Release the video recording resources and camera object resources.
await videoRecorder.release().then(() => {
// Release the video recording resources and camera object resources.
await videoRecorder.release().then(() => {
console.info('release success');
}, failureCallback).catch(catchCallback);
}, this.failureCallback).catch(this.catchCallback);
// Set the related object to null.
videoRecorder = null;
surfaceID = null;
// Set the related object to null.
videoRecorder = undefined;
surfaceID = undefined;
}
}
```
# Using Native APIs in Application Projects
OpenHarmony applications need to use JavaScript (JS) when calling native APIs. The napi interfaces provided by the **arkui_napi** repository are used to implement the interaction with JS. Currently, the **arkui_napi** repository supports some third-party **Node.js** interfaces. The names of the napi interfaces are the same as those in the third-party **Node.js**. For details about the interfaces supported, see `libnapi.ndk.json` in this repository.
OpenHarmony applications use JavaScript (JS) when calling native APIs. The native APIs (NAPIs) provided by the **arkui_napi** repository are used to implement the interaction with JS. Currently, the **arkui_napi** repository supports some third-party **Node.js** interfaces. The names of the NAPIs are the same as those in the third-party **Node.js**. For details about the interfaces supported, see `libnapi.ndk.json` in this repository.
## How to Develop
The IDE has a default project that uses native APIs. You can choose `File` > `New` > `Create Project` to create a `Native C++` project. The cpp directory is generated in the main directory. You can use the napi interfaces provided by the **arkui_napi** repository for development.
The IDE has a default project that uses NAPIs. You can choose `File` > `New` > `Create Project` to create a `Native C++` project. The **cpp** directory is generated in the **main** directory. You can use the NAPIs provided by the **arkui_napi** repository for development.
You can `import` the native .so that contains the JS processing logic. For example, `import hello from 'libhello.so'` to use the **libhello.so** capability. Then, the JS object created using the NAPI interface can be passed to the `hello` object of the application to call the native capability.
You can `import` the native .so that contains the JS processing logic. For example, `import hello from 'libhello.so'` to use the **libhello.so** capability. Then, the JS object created using the NAPI can be passed to the `hello` object of the application to call the native capability.
## Development Guidelines
### Registration
* Add **static** to the **nm_register_func** function to prevent symbol conflicts with other .so files.
* The name of the module registration entry, that is, the function modified by **\_\_attribute\_\_((constructor))**, must be unique.
* The name of the module registration entry, that is, the function decorated by **\_\_attribute\_\_((constructor))**, must be unique.
### .so Naming Rules
Each module has a .so file. For example, if the module name is `hello`, name the .so file **libhello.so**. The `nm_modname` field in `napi_module` must be `hello`, which is the same as the module name. The sample code for importing the .so file is `import hello from 'libhello.so'`.
### JS Objects and Threads
The Ark engine prevents napi interfaces from being called to operate JS objects in non-JS threads. Otherwise, the application will crash.
The Ark engine prevents NAPIs from being called to operate JS objects in non-JS threads. Otherwise, the application will crash.
* The napi interfaces can be used only in JS threads.
* **env** is bound to a thread and cannot be used across threads. The JS object created by a native API can be used only in the thread, in which the object is created, that is, the JS object is bound to the **env** of the thread.
* The NAPIs can be used only in JS threads.
* **env** is bound to a thread and cannot be used across threads. The JS object created by a NAPI can be used only in the thread, in which the object is created, that is, the JS object is bound to the **env** of the thread.
### napi_create_async_work
**napi_create_async_work** has two callbacks:
* **execute**: processes service logic asynchronously. This callback is not executed by a JS thread, therefore, it cannot call any NAPI interface. The return value of **execute** is processed by the **complete** callback.
* **execute**: processes service logic asynchronously. This callback is not executed by a JS thread; therefore, it cannot call any NAPI. The return value of **execute** is processed by the **complete** callback.
* **complete**: calls the napi interface to encapsulate the return value of **execute** into a JS object and return it for processing. This callback is executed by a JS thread.
* **complete**: calls the NAPI to encapsulate the return value of **execute** into a JS object and return it for processing. This callback is executed by a JS thread.
```c++
napi_status napi_create_async_work(napi_env env,
......@@ -45,7 +45,7 @@ napi_status napi_create_async_work(napi_env env,
## Example 1 Encapsulating Synchronous and Asynchronous APIs for the Storage Module
## Example 1: Encapsulating Synchronous and Asynchronous APIs for the Storage Module
### Overview
......@@ -131,7 +131,7 @@ static napi_value JSStorageGetSync(napi_env env, napi_callback_info info)
char value[128] = {0};
size_t valueLen = 0;
// parse parameters
// Parse parameters.
for (size_t i = 0; i < argc; i++) {
napi_valuetype valueType;
napi_typeof(env, argv[i], &valueType);
......@@ -212,7 +212,7 @@ static napi_value JSStorageGet(napi_env env, napi_callback_info info)
napi_create_async_work(
env, nullptr, resource,
// Callback 1: This callback contains the service logic to be asynchronously executed and is asynchronously executed by the napi interface. Do not operate JS objects using the napi interface because the execution is asynchronous.
// Callback 1: This callback contains the service logic to be asynchronously executed and is asynchronously executed by the NAPI. Do not operate JS objects using theNAPI because the execution is asynchronous.
[](napi_env env, void* data) {
StorageAsyncContext* asyncContext = (StorageAsyncContext*)data;
auto itr = gKeyValueStorage.find(asyncContext->key);
......@@ -239,10 +239,10 @@ static napi_value JSStorageGet(napi_env env, napi_callback_info info)
if (asyncContext->deferred) {
// If a promise is used, check the result of callback 1.
if (!asyncContext->status) {
// Triggered when callback 1 is successful (status is 1), that is, invoke the callback passed in then in the promise.
// Triggered when callback 1 is successful (status is 1), that is, to invoke the callback passed in then in the promise.
napi_resolve_deferred(env, asyncContext->deferred, result[1]);
} else {
// Triggered when callback 1 fails (status is 0), that is, invoke the callback passed in catch in the promise.
// Triggered when callback 1 fails (status is 0), that is, to invoke the callback passed in catch in the promise.
napi_reject_deferred(env, asyncContext->deferred, result[0]);
}
} else {
......@@ -287,11 +287,11 @@ export default {
## Example 2 Binding Native and JS Objects for the NetServer Module
## Example 2: Binding Native and JS Objects for the NetServer Module
### Overview
This example shows how to implement the `on/off/once` method and bind C++ and JS objects using the **wrap** API. The NetServer module implements a network service.
This example shows how to implement the `on/off/once` method and bind C++ and JS objects using the **wrap** API. The NetServer module implements the network service.
### API Declaration
......@@ -486,11 +486,11 @@ export default {
## Example 3 Calling Back a JS API in a Non-JS Thread
## Example 3: Calling Back a JS API in a Non-JS Thread
### Overview
This example describes how to invoke a JS callback in a non-JS thread. For example, a sensor listener is registered for a JS application. The sensor data is reported by an SA. When the SA invokes the client through Inter-Process Communication (IPC), the execution thread is an IPC thread, which is different from the JS thread of the application. In this case, the JS callback must be thrown to the JS thread to execute. Otherwise, the application will crash.
This example describes how to invoke a JS callback in a non-JS thread. For example, a sensor listener is registered for a JS application. The sensor data is reported by an SA. When the SA invokes the client through Inter-Process Communication (IPC), the execution thread is an IPC thread, which is different from the JS thread of the SA. In this case, the JS callback must be thrown to the JS thread to execute. Otherwise, the application will crash.
### Implementation
......@@ -513,7 +513,7 @@ static napi_value CallbackExport(napi_env env, napi_value exports)
return exports;
}
// Define the callback
// Define the callback.
static napi_module callbackModule = {
.nm_version = 1,
.nm_flags = 0,
......@@ -524,7 +524,7 @@ static napi_module callbackModule = {
.reserved = { 0 },
};
// Register the callback
// Register the callback.
extern "C" __attribute__((constructor)) void CallbackTestRegister()
{
napi_module_register(&callbackModule);
......@@ -574,7 +574,7 @@ void callbackTest(CallbackContext* context)
return;
}
// Call napi interfaces.
// Call the NAPIs.
napi_value callback = nullptr;
napi_get_reference_value(context->env, context->callbackRef, &callback);
napi_value retArg;
......
......@@ -5,7 +5,7 @@
All the application resource files, such as strings, images, and audio files, are stored in the **resources** directory, allowing you to easily access, use, and maintain them. The **resources** directory consists of two types of sub-directories: the **base** sub-directory and qualifiers sub-directories, and the **rawfile** sub-directory. For details, see Categories of the **resources** directory.
Example of the **resources** directory:
Example of the **resources** directory:
```
resources
......@@ -22,13 +22,13 @@ resources
|---rawfile // Default directory
```
**Table 1** Categories of the **resources** directory
**Table 1** Categories of the **resources** directory
| Category | base&nbsp;and&nbsp;Qualifiers&nbsp;Sub-directories | rawfile&nbsp;Sub-directory |
| Category | base and Qualifiers Sub-directories | rawfile Sub-directory |
| -------- | -------- | -------- |
| Structure | Sub-directories&nbsp;are&nbsp;structured&nbsp;in&nbsp;two&nbsp;levels.&nbsp;The&nbsp;directory&nbsp;name&nbsp;must&nbsp;comply&nbsp;with&nbsp;specified&nbsp;naming&nbsp;conventions&nbsp;so&nbsp;that&nbsp;its&nbsp;target&nbsp;resource&nbsp;file&nbsp;in&nbsp;the&nbsp;correct&nbsp;directory&nbsp;can&nbsp;be&nbsp;matched&nbsp;based&nbsp;on&nbsp;the&nbsp;device&nbsp;status.<br/>&nbsp;&nbsp;The&nbsp;**base**&nbsp;sub-directory&nbsp;and&nbsp;qualifiers&nbsp;sub-directories&nbsp;are&nbsp;the&nbsp;first&nbsp;level&nbsp;of&nbsp;sub-directories&nbsp;under&nbsp;**resources**.<br/>-&nbsp;The&nbsp;**base**&nbsp;sub-directory&nbsp;is&nbsp;generated&nbsp;by&nbsp;default.&nbsp;If&nbsp;no&nbsp;qualifiers&nbsp;sub-directories&nbsp;in&nbsp;the&nbsp;**resources**&nbsp;directory&nbsp;of&nbsp;the&nbsp;application&nbsp;match&nbsp;the&nbsp;device&nbsp;status,&nbsp;the&nbsp;resource&nbsp;file&nbsp;in&nbsp;the&nbsp;**base**&nbsp;sub-directory&nbsp;will&nbsp;be&nbsp;automatically&nbsp;referenced.<br/>-&nbsp;You&nbsp;need&nbsp;to&nbsp;create&nbsp;qualifiers&nbsp;sub-directories&nbsp;on&nbsp;your&nbsp;own.&nbsp;Each&nbsp;directory&nbsp;name&nbsp;consists&nbsp;of&nbsp;one&nbsp;or&nbsp;more&nbsp;qualifiers&nbsp;that&nbsp;represent&nbsp;the&nbsp;application&nbsp;scenarios&nbsp;or&nbsp;device&nbsp;characteristics.&nbsp;For&nbsp;details,&nbsp;see&nbsp;[Qualifiers&nbsp;Sub-directories](#qualifiers-sub-directories).<br/>Resource&nbsp;group&nbsp;sub-directories&nbsp;are&nbsp;located&nbsp;at&nbsp;the&nbsp;second&nbsp;level&nbsp;of&nbsp;sub-directories&nbsp;to&nbsp;store&nbsp;basic&nbsp;elements&nbsp;such&nbsp;as&nbsp;strings,&nbsp;colors,&nbsp;and&nbsp;boolean&nbsp;values,&nbsp;as&nbsp;well&nbsp;as&nbsp;resource&nbsp;files&nbsp;such&nbsp;as&nbsp;media,&nbsp;animations,&nbsp;and&nbsp;layouts.&nbsp;For&nbsp;details,&nbsp;see&nbsp;[Resource&nbsp;Group&nbsp;Sub-directories](#resource-group-sub-directories). | You&nbsp;can&nbsp;create&nbsp;multiple&nbsp;levels&nbsp;of&nbsp;sub-directories&nbsp;with&nbsp;custom&nbsp;directory&nbsp;names.&nbsp;They&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;store&nbsp;various&nbsp;resource&nbsp;files.<br/>However,&nbsp;resource&nbsp;files&nbsp;in&nbsp;the&nbsp;**rawfile**&nbsp;sub-directory&nbsp;will&nbsp;not&nbsp;be&nbsp;matched&nbsp;based&nbsp;on&nbsp;the&nbsp;device&nbsp;status. |
| Compilation | Resource&nbsp;files&nbsp;in&nbsp;the&nbsp;sub-directories&nbsp;are&nbsp;compiled&nbsp;into&nbsp;binary&nbsp;files,&nbsp;and&nbsp;each&nbsp;resource&nbsp;file&nbsp;is&nbsp;assigned&nbsp;an&nbsp;ID. | Resource&nbsp;files&nbsp;in&nbsp;the&nbsp;sub-directory&nbsp;are&nbsp;directly&nbsp;packed&nbsp;into&nbsp;the&nbsp;application&nbsp;without&nbsp;being&nbsp;compiled,&nbsp;and&nbsp;no&nbsp;IDs&nbsp;will&nbsp;be&nbsp;assigned&nbsp;to&nbsp;the&nbsp;resource&nbsp;files. |
| Reference | Resource&nbsp;files&nbsp;in&nbsp;the&nbsp;sub-directories&nbsp;are&nbsp;referenced&nbsp;based&nbsp;on&nbsp;the&nbsp;resource&nbsp;type&nbsp;and&nbsp;resource&nbsp;name. | Resource&nbsp;files&nbsp;in&nbsp;the&nbsp;sub-directories&nbsp;are&nbsp;referenced&nbsp;based&nbsp;on&nbsp;the&nbsp;specified&nbsp;file&nbsp;path&nbsp;and&nbsp;file&nbsp;name. |
| Structure | Sub-directories are structured in two levels. The directory name must comply with specified naming conventions so that its target resource file in the correct directory can be matched based on the device status.<br/> The **base** sub-directory and qualifiers sub-directories are the first level of sub-directories under **resources**.<br/>- The **base** sub-directory is generated by default. If no qualifiers sub-directories in the **resources** directory of the application match the device status, the resource file in the **base** sub-directory will be automatically referenced.<br/>- You need to create qualifiers sub-directories on your own. Each directory name consists of one or more qualifiers that represent the application scenarios or device characteristics. For details, see [Qualifiers Sub-directories](#qualifiers-sub-directories).<br/>Resource group sub-directories are located at the second level of sub-directories to store basic elements such as strings, colors, and boolean values, as well as resource files such as media, animations, and layouts. For details, see [Resource Group Sub-directories](#resource-group-sub-directories). | You can create multiple levels of sub-directories with custom directory names. They can be used to store various resource files.<br/>However, resource files in the **rawfile** sub-directory will not be matched based on the device status. |
| Compilation | Resource files in the sub-directories are compiled into binary files, and each resource file is assigned an ID. | Resource files in the sub-directory are directly packed into the application without being compiled, and no IDs will be assigned to the resource files. |
| Reference | Resource files in the sub-directories are referenced based on the resource type and resource name. | Resource files in the sub-directories are referenced based on the specified file path and file name. |
## Qualifiers Sub-directories
......@@ -39,21 +39,22 @@ The name of a qualifiers sub-directory consists of one or more qualifiers that r
- Qualifiers are ordered in the following sequence: _MCC_MNC-language_script_country/region-screen orientation-device type-color mode-screen density_. You can select one or multiple qualifiers to name your sub-directory based on your application scenarios and device characteristics.
- Separation between qualifiers: The language, script, and country/region qualifiers are separated using underscores (_); the MNC and MCC qualifiers are also separated using underscores (_); other qualifiers are separated using hyphens (-). For example, **zh_Hant_CN** and **zh_CN-car-ldpi**.
- Separation between qualifiers: The language, script, and country/region qualifiers are separated using underscores (\_); the MNC and MCC qualifiers are also separated using underscores (\_); other qualifiers are separated using hyphens (-). For example, **zh_Hant_CN** and **zh_CN-car-ldpi**.
- Value range of qualifiers: The value of each qualifier must meet the requirements. Otherwise, the resource files in the sub-directory cannot be matched.
**Table 2** Requirements for qualifier values
| Qualifier&nbsp;Type | Description&nbsp;and&nbsp;Value&nbsp;Range |
| Qualifier Type | Description and Value Range |
| -------- | -------- |
| MCC&amp;MNC | Indicates&nbsp;the&nbsp;MCC&nbsp;and&nbsp;MNC,&nbsp;which&nbsp;are&nbsp;obtained&nbsp;from&nbsp;the&nbsp;network&nbsp;where&nbsp;the&nbsp;device&nbsp;is&nbsp;registered.&nbsp;The&nbsp;MCC&nbsp;can&nbsp;be&nbsp;either&nbsp;followed&nbsp;by&nbsp;the&nbsp;MNC&nbsp;with&nbsp;an&nbsp;underscore&nbsp;(_)&nbsp;in&nbsp;between&nbsp;or&nbsp;be&nbsp;used&nbsp;independently.&nbsp;For&nbsp;example,&nbsp;**mcc460**&nbsp;represents&nbsp;China,&nbsp;and&nbsp;**mcc460_mnc00**&nbsp;represents&nbsp;China&nbsp;Mobile.<br/>For&nbsp;details&nbsp;about&nbsp;the&nbsp;value&nbsp;range,&nbsp;refer&nbsp;to&nbsp;**ITU-T&nbsp;E.212**&nbsp;(the&nbsp;international&nbsp;identification&nbsp;plan&nbsp;for&nbsp;public&nbsp;networks&nbsp;and&nbsp;subscriptions). |
| Language | Indicates&nbsp;the&nbsp;language&nbsp;used&nbsp;by&nbsp;the&nbsp;device.&nbsp;The&nbsp;value&nbsp;consists&nbsp;of&nbsp;two&nbsp;or&nbsp;three&nbsp;lowercase&nbsp;letters,&nbsp;for&nbsp;example,&nbsp;**zh**&nbsp;indicates&nbsp;Chinese,&nbsp;**en**&nbsp;indicates&nbsp;English,&nbsp;and&nbsp;**mai**&nbsp;indicates&nbsp;Maithili.<br/>For&nbsp;details&nbsp;about&nbsp;the&nbsp;value&nbsp;range,&nbsp;refer&nbsp;to&nbsp;**ISO&nbsp;639**&nbsp;(codes&nbsp;for&nbsp;the&nbsp;representation&nbsp;of&nbsp;names&nbsp;of&nbsp;languages). |
| Script | Indicates&nbsp;the&nbsp;script&nbsp;type&nbsp;used&nbsp;by&nbsp;the&nbsp;device.&nbsp;The&nbsp;value&nbsp;starts&nbsp;with&nbsp;one&nbsp;uppercase&nbsp;letter&nbsp;followed&nbsp;by&nbsp;three&nbsp;lowercase&nbsp;letters,&nbsp;for&nbsp;example,&nbsp;**Hans**&nbsp;indicates&nbsp;simplified&nbsp;Chinese&nbsp;and&nbsp;**Hant**&nbsp;indicates&nbsp;traditional&nbsp;Chinese.<br/>For&nbsp;details&nbsp;about&nbsp;the&nbsp;value&nbsp;range,&nbsp;refer&nbsp;to&nbsp;**ISO&nbsp;15924**&nbsp;(codes&nbsp;for&nbsp;the&nbsp;representation&nbsp;of&nbsp;names&nbsp;of&nbsp;scripts). |
| Country/Region | Indicates&nbsp;the&nbsp;country&nbsp;or&nbsp;region&nbsp;where&nbsp;a&nbsp;user&nbsp;is&nbsp;located.&nbsp;The&nbsp;value&nbsp;consists&nbsp;of&nbsp;two&nbsp;or&nbsp;three&nbsp;uppercase&nbsp;letters&nbsp;or&nbsp;three&nbsp;digits,&nbsp;for&nbsp;example,&nbsp;**CN**&nbsp;indicates&nbsp;China&nbsp;and&nbsp;**GB**&nbsp;indicates&nbsp;the&nbsp;United&nbsp;Kingdom.<br/>For&nbsp;details&nbsp;about&nbsp;the&nbsp;value&nbsp;range,&nbsp;refer&nbsp;to&nbsp;**ISO&nbsp;3166-1**&nbsp;(codes&nbsp;for&nbsp;the&nbsp;representation&nbsp;of&nbsp;names&nbsp;of&nbsp;countries&nbsp;and&nbsp;their&nbsp;subdivisions). |
| Screen&nbsp;orientation | Indicates&nbsp;the&nbsp;screen&nbsp;orientation&nbsp;of&nbsp;the&nbsp;device.&nbsp;The&nbsp;value&nbsp;can&nbsp;be:<br/>-&nbsp;**vertical**:&nbsp;portrait&nbsp;orientation<br/>-&nbsp;**horizontal**:&nbsp;landscape&nbsp;orientation |
| Device&nbsp;type | Indicates&nbsp;the&nbsp;device&nbsp;type.&nbsp;The&nbsp;value&nbsp;can&nbsp;be:<br/>-&nbsp;**phone**:&nbsp;smartphones<br/>-&nbsp;**tablet**:&nbsp;tablets<br/>-&nbsp;**car**:&nbsp;head&nbsp;units<br/>-&nbsp;**tv**:&nbsp;smart&nbsp;TVs<br/>-&nbsp;**wearable**:&nbsp;wearables |
| Color&nbsp;mode | Indicates&nbsp;the&nbsp;color&nbsp;mode&nbsp;of&nbsp;the&nbsp;device.&nbsp;The&nbsp;value&nbsp;can&nbsp;be:<br/>-&nbsp;**dark**:&nbsp;dark&nbsp;mode<br/>-&nbsp;**light**:&nbsp;light&nbsp;mode |
| Screen&nbsp;density | Indicates&nbsp;the&nbsp;screen&nbsp;density&nbsp;of&nbsp;the&nbsp;device,&nbsp;in&nbsp;dpi.&nbsp;The&nbsp;value&nbsp;can&nbsp;be:<br/>-&nbsp;**sdpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;small-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(SDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(0,&nbsp;120].<br/>-&nbsp;**mdpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;medium-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(MDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(120,&nbsp;160].<br/>-&nbsp;**ldpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;large-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(LDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(160,&nbsp;240].<br/>-&nbsp;**xldpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;extra-large-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(XLDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(240,&nbsp;320].<br/>-&nbsp;**xxldpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;extra-extra-large-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(XXLDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(320,&nbsp;480].<br/>-&nbsp;**xxxldpi**:&nbsp;screen&nbsp;density&nbsp;with&nbsp;extra-extra-extra-large-scale&nbsp;dots&nbsp;per&nbsp;inch&nbsp;(XXXLDPI).&nbsp;This&nbsp;value&nbsp;is&nbsp;applicable&nbsp;for&nbsp;devices&nbsp;with&nbsp;a&nbsp;DPI&nbsp;range&nbsp;of&nbsp;(480,&nbsp;640]. |
| MCC&amp;MNC | Indicates the MCC and MNC, which are obtained from the network where the device is registered. The MCC can be either followed by the MNC with an underscore (_) in between or be used independently. For example, **mcc460** represents China, and **mcc460_mnc00** represents China Mobile.<br/>For details about the value range, refer to **ITU-T E.212** (the international identification plan for public networks and subscriptions). |
| Language | Indicates the language used by the device. The value consists of two or three lowercase letters, for example, **zh** indicates Chinese, **en** indicates English, and **mai** indicates Maithili.<br/>For details about the value range, refer to **ISO 639** (codes for the representation of names of languages). |
| Script | Indicates the script type used by the device. The value starts with one uppercase letter followed by three lowercase letters, for example, **Hans** indicates simplified Chinese and **Hant** indicates traditional Chinese.<br/>For details about the value range, refer to **ISO 15924** (codes for the representation of names of scripts). |
| Country/Region | Indicates the country or region where a user is located. The value consists of two or three uppercase letters or three digits, for example, **CN** indicates China and **GB** indicates the United Kingdom.<br/>For details about the value range, refer to **ISO 3166-1** (codes for the representation of names of countries and their subdivisions). |
| Screen orientation | Indicates the screen orientation of the device. The value can be:<br/>- **vertical**: portrait orientation<br/>- **horizontal**: landscape orientation |
| Device type | Indicates the device type. The value can be:<br/>- **phone**: smartphones<br/>- **tablet**: tablets<br/>- **car**: head units<br/>- **tv**: smart TVs<br/>- **wearable**: wearables |
| Color mode | Indicates the color mode of the device. The value can be:<br/>- **dark**: dark mode<br/>- **light**: light mode |
| Screen density | Indicates the screen density of the device, in dpi. The value can be:<br/>- **sdpi**: screen density with small-scale dots per inch (SDPI). This value is applicable for devices with a DPI range of (0, 120].<br/>- **mdpi**: screen density with medium-scale dots per inch (MDPI). This value is applicable for devices with a DPI range of (120, 160].<br/>- **ldpi**: screen density with large-scale dots per inch (LDPI). This value is applicable for devices with a DPI range of (160, 240].<br/>- **xldpi**: screen density with extra-large-scale dots per inch (XLDPI). This value is applicable for devices with a DPI range of (240, 320].<br/>- **xxldpi**: screen density with extra-extra-large-scale dots per inch (XXLDPI). This value is applicable for devices with a DPI range of (320, 480].<br/>- **xxxldpi**: screen density with extra-extra-extra-large-scale dots per inch (XXXLDPI). This value is applicable for devices with a DPI range of (480, 640]. |
**Rules for Matching Qualifiers Sub-directories and Device Resources**
......@@ -66,14 +67,13 @@ The name of a qualifiers sub-directory consists of one or more qualifiers that r
You can create resource group sub-directories (including element, media, animation, layout, graphic, and profile) in the **base** and qualifiers sub-directories to store resource files of specific types. For details, see Resource group sub-directories.
**Table 3** Resource group sub-directories
**Table 3** Resource group sub-directories
| Resource&nbsp;Group&nbsp;Sub-directory | Description | Resource&nbsp;File |
| Resource Group Sub-directory | Description | Resource File |
| -------- | -------- | -------- |
| element | Indicates&nbsp;element&nbsp;resources.&nbsp;Each&nbsp;type&nbsp;of&nbsp;data&nbsp;is&nbsp;represented&nbsp;by&nbsp;a&nbsp;JSON&nbsp;file.&nbsp;The&nbsp;options&nbsp;are&nbsp;as&nbsp;follows:<br/>-&nbsp;**boolean**:&nbsp;boolean&nbsp;data<br/>-&nbsp;**color**:&nbsp;color&nbsp;data<br/>-&nbsp;**float**:&nbsp;floating-point&nbsp;data<br/>-&nbsp;**intarray**:&nbsp;array&nbsp;of&nbsp;integer<br/>-&nbsp;**integer**:&nbsp;integer&nbsp;data<br/>-&nbsp;**pattern**:&nbsp;pattern&nbsp;data<br/>-&nbsp;**plural**:&nbsp;plural&nbsp;form&nbsp;data<br/>-&nbsp;**strarray**:&nbsp;array&nbsp;of&nbsp;strings<br/>-&nbsp;**string**:&nbsp;string&nbsp;data | It&nbsp;is&nbsp;recommended&nbsp;that&nbsp;files&nbsp;in&nbsp;the&nbsp;**element**&nbsp;sub-directory&nbsp;be&nbsp;named&nbsp;the&nbsp;same&nbsp;as&nbsp;the&nbsp;following&nbsp;files,&nbsp;each&nbsp;of&nbsp;which&nbsp;can&nbsp;contain&nbsp;only&nbsp;data&nbsp;of&nbsp;the&nbsp;same&nbsp;type:<br/>-&nbsp;boolean.json<br/>-&nbsp;color.json<br/>-&nbsp;float.json<br/>-&nbsp;intarray.json<br/>-&nbsp;integer.json<br/>-&nbsp;pattern.json<br/>-&nbsp;plural.json<br/>-&nbsp;strarray.json<br/>-&nbsp;string.json |
| media | Indicates&nbsp;media&nbsp;resources,&nbsp;including&nbsp;non-text&nbsp;files&nbsp;such&nbsp;as&nbsp;images,&nbsp;audios,&nbsp;and&nbsp;videos. | The&nbsp;file&nbsp;name&nbsp;can&nbsp;be&nbsp;customized,&nbsp;for&nbsp;example,&nbsp;**icon.png**. |
| animation | Indicates&nbsp;animation&nbsp;resources,&nbsp;in&nbsp;XML&nbsp;format. | The&nbsp;file&nbsp;name&nbsp;can&nbsp;be&nbsp;customized,&nbsp;for&nbsp;example,&nbsp;**zoom_in.xml**. |
| layout | Indicates&nbsp;layout&nbsp;resources,&nbsp;in&nbsp;XML&nbsp;format. | The&nbsp;file&nbsp;name&nbsp;can&nbsp;be&nbsp;customized,&nbsp;for&nbsp;example,&nbsp;**home_layout.xml**. |
| graphic | Indicates&nbsp;graphic&nbsp;resources,&nbsp;in&nbsp;XML&nbsp;format. | The&nbsp;file&nbsp;name&nbsp;can&nbsp;be&nbsp;customized,&nbsp;for&nbsp;example,&nbsp;**notifications_dark.xml**. |
| profile | Indicates&nbsp;other&nbsp;types&nbsp;of&nbsp;files,&nbsp;which&nbsp;are&nbsp;stored&nbsp;in&nbsp;their&nbsp;raw&nbsp;formats. | The&nbsp;file&nbsp;name&nbsp;can&nbsp;be&nbsp;customized. |
| element | Indicates element resources. Each type of data is represented by a JSON file. The options are as follows:<br/>- **boolean**: boolean data<br/>- **color**: color data<br/>- **float**: floating-point data<br/>- **intarray**: array of integer<br/>- **integer**: integer data<br/>- **pattern**: pattern data<br/>- **plural**: plural form data<br/>- **strarray**: array of strings<br/>- **string**: string data | It is recommended that files in the **element** sub-directory be named the same as the following files, each of which can contain only data of the same type:<br/>- boolean.json<br/>- color.json<br/>- float.json<br/>- intarray.json<br/>- integer.json<br/>- pattern.json<br/>- plural.json<br/>- strarray.json<br/>- string.json |
| media | Indicates media resources, including non-text files such as images, audios, and videos. | The file name can be customized, for example, **icon.png**. |
| animation | Indicates animation resources, in XML format. | The file name can be customized, for example, **zoom_in.xml**. |
| layout | Indicates layout resources, in XML format. | The file name can be customized, for example, **home_layout.xml**. |
| graphic | Indicates graphic resources, in XML format. | The file name can be customized, for example, **notifications_dark.xml**. |
| profile | Indicates other types of files, which are stored in their raw formats. | The file name can be customized. |
......@@ -18,10 +18,10 @@ OpenHarmony provides a UI development framework, known as ArkUI. ArkUI provides
ArkUI comes with two development paradigms: JavaScript-based web-like development paradigm (web-like development paradigm for short) and TypeScript-based declarative development paradigm (declarative development paradigm for short). You can choose whichever development paradigm that aligns with your practice.
| **Development&nbsp;Paradigm** | **Language** | **UI&nbsp;Update&nbsp;Mode** | **Applicable&nbsp;To** | **Intended&nbsp;Audience** |
| **Development Paradigm** | **Language** | **UI Update Mode** | **Applicable To** | **Intended Audience** |
| -------- | -------- | -------- | -------- | -------- |
| Web-like&nbsp;development&nbsp;paradigm | JavaScript | Data-driven | Applications&nbsp;and&nbsp;service&nbsp;widgets&nbsp;with&nbsp;simple&nbsp;UIs | Frontend&nbsp;web&nbsp;developers |
| Declarative&nbsp;development&nbsp;paradigm | Extended&nbsp;TypeScript&nbsp;(eTS) | Data-driven | Applications&nbsp;involving&nbsp;technological&nbsp;sophistication&nbsp;and&nbsp;teamwork | Mobile&nbsp;application&nbsp;and&nbsp;system&nbsp;application&nbsp;developers |
| Web-like development paradigm | JavaScript | Data-driven | Applications and service widgets with simple UIs | Frontend web developers |
| Declarative development paradigm | Extended TypeScript (eTS) | Data-driven | Applications involving technological sophistication and teamwork | Mobile application and system application developers |
For DevEco Studio V2.2 Beta1 and later versions, both the traditional coding mode and the low-code mode are supported when the JS language is used for development.
......
# Getting Started with eTS in the Low-Code Approach
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> This feature is supported in DevEco Studio V3.0 Beta3 and later versions.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>This feature is supported in DevEco Studio V3.0 Beta3 and later versions.
>
> The component lineup that supports low-code development in eTS is now at its preliminary stage and will be expanding in coming versions.
>
......@@ -21,7 +20,7 @@ You can develop applications or services in the low-code approach using either o
## Creating a Project That Supports Low-Code Development
1. Open DevEco Studio, choose **File** &gt; **New** &gt; **Create Project**, select **Empty Ability**, and click **Next**.
1. In DevEco Studio, if no project is open, click **Create Project**; if a project is already open, choose **File** &gt; **New** &gt; **Create Project**. Then, select **Empty Ability** and click **Next**.
![en-us_image_0000001233528152](figures/en-us_image_0000001233528152.png)
......@@ -50,26 +49,32 @@ After the project synchronization is complete, the default first page contains t
Add **Column**, **Text**, and **Button** components to the first page. A column is a container component whose child components are vertically arranged. For details, see [Column](../reference/arkui-ts/ts-container-column.md).
1. Delete the existing template components from the canvas.<a name="delete_origin_content"></a>
Open the index.visual file, right-click the existing template components on the canvas, and choose **Delete** from the shortcut menu to delete them. Below is an illustration of the operations.
![en-us_image_0000001233208980](figures/en-us_image_0000001233208980.gif)
Open the **index.visual** file, right-click the existing template components on the canvas, and choose **Delete** from the shortcut menu to delete them. Below is an illustration of the operations.
![en-us_image_0000001233208980](figures/en-us_image_0000001233208980.gif)
2. Add a **Column** component and set its styles and attributes.<a name="add_container"></a>
Drag the **Column** component from the **UI Control** area to the canvas. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001233048996](figures/en-us_image_0000001233048996.png)**General** and set **Height** to **100%** so that the component fills the entire screen. Click ![en-us_image_0000001233368860](figures/en-us_image_0000001233368860.png)**Feature** and set **AlignItems** to **center** so that the child components of the **Column** component are centered along the horizontal axis. Below is an illustration of the operations.
![en-us_image_0000001277488977](figures/en-us_image_0000001277488977.gif)
3. Add a **Text** component.
Drag the **Text** component from the **UI Control** area to the canvas and then to the center area of the **Column** component. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001277608813](figures/en-us_image_0000001277608813.png)**Feature**, set **Content** of the **Text** component to **this.message** (that is, **Hello World**), set **FontSize** to **30fp**, and set **TextAlign** to **center**. Then, select the **Text** component on the canvas and drag its corners to fully display the text. Below is an illustration of the operations.
![en-us_image_0000001235731706](figures/en-us_image_0000001235731706.gif)
4. Add a **Button** component.
Drag the **Button** component from the **UI Control** area to the canvas and then to a position under the **Text** component. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001277728577](figures/en-us_image_0000001277728577.png)**General** and set **Height** of the **Button** component to **40vp**. Click ![en-us_image_0000001277809337](figures/en-us_image_0000001277809337.png)**Feature** and set **Label** to **Next** and **FontSize** to **25fp**. Below is an illustration of the operations.
![en-us_image_0000001235732402](figures/en-us_image_0000001235732402.gif)
![en-us_image_0000001235732402](figures/en-us_image_0000001235732402.gif)
5. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer.
5. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer. Below is how the first page looks in the Previewer.
Below is how the first page looks in the Previewer.
![en-us_image_0000001235892798](figures/en-us_image_0000001235892798.png)
......@@ -77,9 +82,10 @@ Add **Column**, **Text**, and **Button** components to the first page. A column
## Building the Second Page
1. Create the second page.
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **ets** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Visual**, name the page **second**, and click **Finish**. Below is the structure of the **pages** folder.
![en-us_image_0000001233368868](figures/en-us_image_0000001233368868.png)
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **ets** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Visual**, name the page **second**, and click **Finish**. Below, you can see the structure of the **pages** folder.
![en-us_image_0000001233368868](figures/en-us_image_0000001233368868.png)
2. [Delete the existing template components from the canvas.](#delete_origin_content)
......@@ -108,6 +114,7 @@ Add **Column**, **Text**, and **Button** components to the first page. A column
![en-us_image_0000001280255513](figures/en-us_image_0000001280255513.gif)
5. Add a **Button** component.
Drag the **Button** component from the **UI Control** area to the canvas and then to a position under the **Text** component. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001233528160](figures/en-us_image_0000001233528160.png)**General** and set **Height** of the **Button** component to **40vp**. Click ![en-us_image_0000001277728597](figures/en-us_image_0000001277728597.png)**Feature** and set **Value** to **Back** and **FontSize** to **25fp**. Below is an illustration of the operations.
![en-us_image_0000001280383937](figures/en-us_image_0000001280383937.gif)
......@@ -118,7 +125,9 @@ Add **Column**, **Text**, and **Button** components to the first page. A column
You can implement page redirection through the page router, which finds the target page based on the page URI. Import the **router** module and then perform the steps below:
1. Implement redirection from the first page to the second page.
In the files of the first page, bind the **onclick** method to the button so that clicking the button redirects the user to the second page. This operation needs to be completed in both .ets and .visual files.
- In the **index.ets** file:
```
......@@ -144,11 +153,12 @@ You can implement page redirection through the page router, which finds the targ
}
```
- In the index.visual file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001233209020](figures/en-us_image_0000001233209020.png)**Events** and set **OnClick** to **this.onclick**.
- In the **index.visual** file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001233209020](figures/en-us_image_0000001233209020.png)**Events** and set **OnClick** to **this.onclick**.
![en-us_image_0000001235745716](figures/en-us_image_0000001235745716.png)
2. Implement redirection from the second page to the first page.
In the files of the second page, bind the **back** method to the **Back** button so that clicking the button redirects the user back to the first page. This operation needs to be completed in both .ets and .visual files.
- In the **second.ets** file:
......@@ -174,7 +184,7 @@ You can implement page redirection through the page router, which finds the targ
}
}
```
- In the second.visual file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001233368900](figures/en-us_image_0000001233368900.png)**Events** and set **OnClick** to **this.back**.
- In the **second.visual** file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001233368900](figures/en-us_image_0000001233368900.png)**Events** and set **OnClick** to **this.back**.
![en-us_image_0000001280385809](figures/en-us_image_0000001280385809.png)
......
# Getting Started with eTS in the Traditional Coding Approach
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> To use eTS, your DevEco Studio must be V3.0.0.601 Beta1 or later.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>To use eTS, your DevEco Studio must be V3.0.0.601 Beta1 or later.
>
> For best possible results, use [DevEco Studio V3.0.0.900 Beta3](https://developer.harmonyos.com/cn/develop/deveco-studio#download_beta_openharmony) for your development.
## Creating an eTS Project
1. Open DevEco Studio, choose **File** &gt; **New** &gt; **Create Project**, select **Empty Ability**, and click **Next**.
1. In DevEco Studio, if no project is open, click **Create Project**; if a project is already open, choose **File** &gt; **New** &gt; **Create Project**. Then, select **Empty Ability** and click **Next**.
![en-us_image_0000001223556342](figures/en-us_image_0000001223556342.png)
......@@ -21,14 +20,14 @@
## eTS Project Files
- **entry** : OpenHarmony project module, which can be built into an ability package (HAP).
- **entry** : OpenHarmony project module, which can be built into an ability package ([HAP](../../glossary.md#hap)).
- **src &gt; main &gt; ets** : a collection of eTS source code.
- **src &gt; main &gt; ets &gt; MainAbility** : entry to your application/service.
- **src &gt; main &gt; ets &gt; MainAbility &gt; pages** : pages contained in **MainAbility**.
- **src &gt; main &gt; ets &gt; MainAbility &gt; app.ets** : ability lifecycle file.
- **src &gt; main &gt; resources** : a collection of resource files used by your application/service, such as graphics, multimedia, character strings, and layout files.
- **src &gt; main &gt; config.json** : module configuration file. This file describes the global configuration information of the application/service, the device-specific configuration information, and the configuration information of the HAP file.
- **build-profile.json5** : module information and build configuration options, including **buildOption target**.
- **build-profile.json5** : current module information and build configuration options, including **buildOption target**.
- **hvigorfile.js** : module-level compilation and build task script. You can customize related tasks and code implementation.
- **build-profile.json5** : application-level configuration information, including the signature and product configuration.
- **hvigorfile.js** : application-level compilation and build task script.
......@@ -37,6 +36,7 @@
## Building the First Page
1. Use the **Text** component.
After the project synchronization is complete, choose **entry** &gt; **src** &gt; **main** &gt; **ets** &gt; **MainAbility** &gt; **pages** in the **Project** window and open the **index.ets** file. You can see that the file contains a **&lt;Text&gt;** component. The sample code in the **index.ets** file is shown below:
......@@ -61,6 +61,7 @@
```
2. Add a **&lt;Button&gt;** component.
On the default page, add a **&lt;Button&gt;** component to accept user clicks and implement redirection to another page. The sample code in the **index.ets** file is shown below:
......@@ -97,7 +98,9 @@
}
```
3. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer. Below is how the first page looks on the Previewer.
3. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer.
Below is how the first page looks on the Previewer.
![en-us_image_0000001216239356](figures/en-us_image_0000001216239356.png)
......@@ -105,11 +108,13 @@
## Building the Second Page
1. Create the second page.
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **ets** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Page**, name the page **second**, and click **Finish**. Below is the structure of the **pages** folder:
![en-us_image_0000001223397122](figures/en-us_image_0000001223397122.png)
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **ets** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Page**, name the page **second**, and click **Finish**. Below, you can see the structure of the **pages** folder.
![en-us_image_0000001223397122](figures/en-us_image_0000001223397122.png)
2. Add **&lt;Text&gt;** and **&lt;Button&gt;** components.
Add **&lt;Text&gt;** and **&lt;Button&gt;** components and set their styles, as you do for the first page. The sample code in the **second.ets** file is shown below:
......@@ -151,6 +156,7 @@
You can implement page redirection through the page router, which finds the target page based on the page URI. Import the **router** module and then perform the steps below:
1. Implement redirection from the first page to the second page.
In the **index.ets** file of the first page, bind the **onClick** event to the **Next** button so that clicking the button redirects the user to the second page. The sample code in the **index.ets** file is shown below:
......@@ -194,6 +200,7 @@ You can implement page redirection through the page router, which finds the targ
```
2. Implement redirection from the second page to the first page.
In the **second.ets** file of the second page, bind the **onClick** event to the **Back** button so that clicking the button redirects the user back to the first page. The sample code in the **second.ets** file is shown below:
......
# Getting Started with JavaScript in the Low-Code Approach
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> This feature will be available in DevEco Studio V2.2 Beta1 and later versions.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>This feature will be available in DevEco Studio V2.2 Beta1 and later versions.
>
> For best possible results, use [DevEco Studio V3.0.0.900 Beta3](https://developer.harmonyos.com/cn/develop/deveco-studio#download_beta_openharmony) for your development.
......@@ -19,10 +18,10 @@ You can develop applications or services in the low-code approach using either o
## Creating a Project That Supports Low-Code Development
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> This feature is available in DevEco Studio 3.0 Beta2 and later versions and works with compileSdkVersion 7 or later.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>This feature is available in DevEco Studio 3.0 Beta2 and later versions and works with compileSdkVersion 7 or later.
>
1. Open DevEco Studio, choose **File** &gt; **New** &gt; **Create Project**, select **Empty Ability**, and click **Next**.
1. In DevEco Studio, if no project is open, click **Create Project**; if a project is already open, choose **File** &gt; **New** &gt; **Create Project**. Then, select **Empty Ability** and click **Next**.
![en-us_image_0000001268198893](figures/en-us_image_0000001268198893.png)
2. Go to the project configuration page, select **Enable Super Visual**, set **UI Syntax** to **JS**, and retain the default values for other parameters.
......@@ -39,8 +38,8 @@ After the project synchronization is complete, a low-code directory structure is
![en-us_image_0000001223558810](figures/en-us_image_0000001223558810.png)
- **entry &gt; src &gt; main &gt; js &gt; MainAbility &gt; pages &gt; index &gt; index.js** : defines logical relationships, such as data and events, used on low-code pages. For details, see [JavaScript](../ui/js-framework-syntax-js.md). If multiple low-code development pages are created, a page folder and the corresponding **.js** file will be created for each of these pages.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> To avoid build errors when using the low-code development page, make sure the directory where the corresponding **.js** file is located does not contain **.hml** or **.css** files. For example, in the preceding example, no **.hml** or **.css** file is allowed in **js** &gt; **MainAbility** &gt; **pages** &gt; **index**.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>To avoid build errors when using the low-code development page, make sure the directory where the corresponding **.js** file is located does not contain **.hml** or **.css** files. For example, in the preceding example, no **.hml** or **.css** file is allowed in **js** &gt; **MainAbility** &gt; **pages** &gt; **index**.
>
- **entry &gt; src &gt; main &gt; supervisual &gt; MainAbility &gt; pages &gt; index &gt; index.visual** : stores the data model of the low-code development page. You can double-click the file to open the low-code development page. If multiple low-code development pages are created, a page folder and the corresponding **.visual** file will be created for each of these pages.
......@@ -51,26 +50,33 @@ After the project synchronization is complete, the default first page contains t
Add **Div**, **Text**, and **Button** components to the first page.
1. Delete the existing template components from the canvas.<a name= delete_origin_content></a>
Open the index.visual file, right-click the existing template components on the canvas, and choose **Delete** from the shortcut menu to delete them. Below is an illustration of the operations.
![en-us_image_0000001216600980](figures/en-us_image_0000001216600980.gif)
Open the index.visual file, right-click the existing template components on the canvas, and choose **Delete** from the shortcut menu to delete them. Below is an illustration of the operations.
![en-us_image_0000001216600980](figures/en-us_image_0000001216600980.gif)
2. Add a **Div** component and set its styles and attributes.<a name = add_container></a>
Drag the **Div** component from the **UI Control** area to the canvas. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001260226691](figures/en-us_image_0000001260226691.png)**General** and set **Height** to **100%** so that the component fills the entire screen. Click ![en-us_image_0000001215226858](figures/en-us_image_0000001215226858.png)**Flex**, set **FlexDirection** to **column** so that the main axis of the component is vertical, and set both **JustifyContent** and **AlignItems** to **center** so that the child components of the **Div** component are centered along the main axis and cross axis. Below is an illustration of the operations.
![en-us_image_0000001216448880](figures/en-us_image_0000001216448880.gif)
![en-us_image_0000001216448880](figures/en-us_image_0000001216448880.gif)
3. Add a **Text** component.
Drag the **Text** component from the **UI Control** area to the center area of the **Div** component. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001215066868](figures/en-us_image_0000001215066868.png)**Properties** and set **Content** of the **Text** component to **Hello World**. Click ![en-us_image_0000001215386842](figures/en-us_image_0000001215386842.png)**Feature**, and set **FontSize** to **60px** and **TextAlign** to **center**. Then, select the **Text** component on the canvas and drag its corners to fully display the text. Below is an illustration of the operations.
![en-us_image_0000001216446670](figures/en-us_image_0000001216446670.gif)
4. Add a **Button** component.
Drag the **Button** component from the **UI Control** area to a position under the **Text** component on the canvas. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001260106745](figures/en-us_image_0000001260106745.png)**Properties** and set **Value** of the **Button** component to **Next**. Click ![en-us_image_0000001259866741](figures/en-us_image_0000001259866741.png)**Feature** and set **FontSize** to **40px**. Then, select the **Button** component on the canvas and drag its corners to fully display the text. Below is an illustration of the operations.
![en-us_image_0000001260928361](figures/en-us_image_0000001260928361.gif)
5. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer. Below is how the first page looks on the Previewer.
5. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer.
Below is how the first page looks on the Previewer.
![en-us_image_0000001216288558](figures/en-us_image_0000001216288558.png)
......@@ -78,20 +84,23 @@ Add **Div**, **Text**, and **Button** components to the first page.
## Building the Second Page
1. Create the second page.
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Visual**, name the page **second**, and click **Finish**. Below is the structure of the **pages** folder:
![en-us_image_0000001223882030](figures/en-us_image_0000001223882030.png)
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Visual**, name the page **second**, and click **Finish**. Below, you can see the structure of the **pages** folder.
![en-us_image_0000001223882030](figures/en-us_image_0000001223882030.png)
2. [Delete the existing template components from the canvas.](#delete_origin_content)
3. [Add a Div component and set its styles and attributes.](#add_container)
4. Add a **Text** component.
Drag the **Text** component from the **UI Control** area to the center area of the **Div** component. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001260227453](figures/en-us_image_0000001260227453.png)**Properties** and set **Content** of the **Text** component to **Hi there**. Click ![en-us_image_0000001260107497](figures/en-us_image_0000001260107497.png)**Feature**, and set **FontSize** to **60px** and **TextAlign** to **center**. Then, select the **Text** component on the canvas and drag its corners to fully display the text. Below is an illustration of the operations.
![en-us_image_0000001216614132](figures/en-us_image_0000001216614132.gif)
5. Add a **Button** component.
Drag the **Button** component from the **UI Control** area to a position under the **Text** component on the canvas. In the **Attributes &amp; Styles** area on the right, click ![en-us_image_0000001215227618](figures/en-us_image_0000001215227618.png)**Properties** and set **Value** of the **Button** component to **Back**. Click ![en-us_image_0000001259987441](figures/en-us_image_0000001259987441.png)**Feature** and set **FontSize** to **40px**. Then, select the **Button** component on the canvas and drag its corners to fully display the text. Below is an illustration of the operations.
![en-us_image_0000001261017331](figures/en-us_image_0000001261017331.gif)
......@@ -102,7 +111,9 @@ Add **Div**, **Text**, and **Button** components to the first page.
You can implement page redirection through the [page router](../ui/ui-js-building-ui-routes.md), which finds the target page based on the page URI. Import the **router** module and then perform the steps below:
1. Implement redirection from the first page to the second page.
In the files of the first page, bind the **onclick** method to the button so that clicking the button redirects the user to the second page. This operation needs to be completed in both .js and .visual files.
- In the **index.js** file:
```js
......@@ -122,6 +133,7 @@ You can implement page redirection through the [page router](../ui/ui-js-buildin
![en-us_image_0000001223722586](figures/en-us_image_0000001223722586.png)
2. Implement redirection from the second page to the first page.
In the files of the second page, bind the **back** method to the **Back** button so that clicking the button redirects the user back to the first page.
This operation needs to be completed in both .js and .visual files.
......@@ -137,7 +149,7 @@ You can implement page redirection through the [page router](../ui/ui-js-buildin
}
}
```
- In the second.visual file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001215388262](figures/en-us_image_0000001215388262.png)**Events** and set **Click** to **back**.
- In the **second.visual** file, select the **Button** component on the canvas. In the **Attributes &amp; Styles** area, click ![en-us_image_0000001215388262](figures/en-us_image_0000001215388262.png)**Events** and set **Click** to **back**.
![en-us_image_0000001268082945](figures/en-us_image_0000001268082945.png)
......
# Getting Started with JavaScript in the Traditional Coding Approach
> ![icon-note.gif](public_sys-resources/icon-note.gif) **Note:**
> For best possible results, use [DevEco Studio V3.0.0.900 Beta3](https://developer.harmonyos.com/cn/develop/deveco-studio#download_beta_openharmony) for your development.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>For best possible results, use [DevEco Studio V3.0.0.900 Beta3](https://developer.harmonyos.com/cn/develop/deveco-studio#download_beta_openharmony) for your development.
>
## Creating a JavaScript Project
1. Open DevEco Studio, choose **File** &gt; **New** &gt; **Create Project**, select **Empty Ability**, and click **Next**.
1. In DevEco Studio, if no project is open, click **Create Project**; if a project is already open, choose **File** &gt; **New** &gt; **Create Project**. Then, select **Empty Ability** and click **Next**.
![en-us_image_0000001223558814](figures/en-us_image_0000001223558814.png)
......@@ -19,23 +19,24 @@
## JavaScript Project Files
- **entry** : OpenHarmony project module, which can be built into an ability package (HAP).
- **src &gt; main &gt; js** : a collection of JS source code.
- **src &gt; main &gt; js &gt; MainAbility** : entry to your application/service.
- **src &gt; main &gt; js &gt; MainAbility &gt; i18n** : resources in different languages, for example, UI strings and image paths.
- **src &gt; main &gt; js &gt; MainAbility &gt; pages** : pages contained in **MainAbility**.
- **src &gt; main &gt; js &gt; MainAbility &gt; app.js** : ability lifecycle file.
- **src &gt; main &gt; resources** : a collection of resource files used by your application/service, such as graphics, multimedia, character strings, and layout files.
- **src &gt; main &gt; config.json** : module configuration file. This file describes the global configuration information of the application/service, the device-specific configuration information, and the configuration information of the HAP file.
- **build-profile.json5** : module information and build configuration options, including **buildOption target**.
- **hvigorfile.js** : module-level compilation and build task script. You can customize related tasks and code implementation.
- **build-profile.json5** : application-level configuration information, including the signature and product configuration.
- **hvigorfile.js** : application-level compilation and build task script.
- **entry** : OpenHarmony project module, which can be built into an ability package ([HAP](../../glossary.md#hap)).
- **src &gt; main &gt; js**: a collection of JS source code.
- **src &gt; main &gt; js &gt; MainAbility**: entry to your application/service.
- **src &gt; main &gt; js &gt; MainAbility &gt; i18n**: resources in different languages, for example, UI strings and image paths.
- **src &gt; main &gt; js &gt; MainAbility &gt; pages**: pages contained in **MainAbility**.
- **src &gt; main &gt; js &gt; MainAbility &gt; app.js**: ability lifecycle file.
- **src &gt; main &gt; resources**: a collection of resource files used by your application/service, such as graphics, multimedia, character strings, and layout files.
- **src &gt; main &gt; config.json**: module configuration file. This file describes the global configuration information of the application/service, the device-specific configuration information, and the configuration information of the HAP file.
- **build-profile.json5**: current module information and build configuration options, including **buildOption target**.
- **hvigorfile.js**: module-level compilation and build task script. You can customize related tasks and code implementation.
- **build-profile.json5**: application-level configuration information, including the signature and product configuration.
- **hvigorfile.js**: application-level compilation and build task script.
## Building the First Page
1. Use the **Text** component.
After the project synchronization is complete, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility** &gt; **pages** &gt; **index** in the **Project** window and open the **index.hml** file. You can see that the file contains a **&lt;Text&gt;** component. The sample code in the **index.hml** file is shown below:
......@@ -48,6 +49,7 @@
```
2. Add a button and bind the **onclick** method to this button.
On the default page, add an **&lt;input&gt;** component of the button type to accept user clicks and implement redirection to another page. The sample code in the **index.hml** file is shown below:
......@@ -63,6 +65,7 @@
```
3. Set the page style in the **index.css** file.
From the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility** &gt; **pages** &gt; **index**, open the **index.css** file, and set the page styles, such as the width, height, font size, and spacing. The sample code in the **index.css** file is shown below:
......@@ -96,7 +99,9 @@
}
```
4. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer. Below is how the first page looks on the Previewer.
4. On the toolbar in the upper right corner of the editing window, click **Previewer** to open the Previewer.
Below is how the first page looks on the Previewer.
![en-us_image_0000001216084724](figures/en-us_image_0000001216084724.png)
......@@ -104,11 +109,13 @@
## Building the Second Page
1. Create the second page.
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Page**, name the page **second**, and click **Finish**. Below is the structure of the **second** folder:
![en-us_image_0000001223877210](figures/en-us_image_0000001223877210.png)
In the **Project** window, choose **entry** &gt; **src** &gt; **main** &gt; **js** &gt; **MainAbility**, right-click the **pages** folder, choose **New** &gt; **Page**, name the page **second**, and click **Finish**. Below, you can see the structure of the **second** folder.
![en-us_image_0000001223877210](figures/en-us_image_0000001223877210.png)
2. Add **&lt;Text&gt;** and **&lt;Button&gt;** components.
Add **&lt;Text&gt;** and **&lt;Button&gt;** components and set their styles, as you do for the first page. The sample code in the **second.hml** file is shown below:
......@@ -161,6 +168,7 @@
You can implement page redirection through the [page router](../ui/ui-js-building-ui-routes.md), which finds the target page based on the page URI. Import the **router** module and then perform the steps below:
1. Implement redirection from the first page to the second page.
In the **index.js** file of the first page, bind the **onclick** method to the button so that clicking the button redirects the user to the second page. The sample code in the **index.js** file is shown below:
......@@ -177,6 +185,7 @@ You can implement page redirection through the [page router](../ui/ui-js-buildin
```
2. Implement redirection from the second page to the first page.
In the **second.ets** file of the second page, bind the **back** method to the **Back** button so that clicking the button redirects the user back to the first page. The sample code in the **second.js** file is shown below:
......
# Work Scheduler Callbacks
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
> The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
> The initial APIs of this module are supported since API version 9. API version 9 is a canary version for trial use. The APIs of this version may be unstable.
## Modules to Import
......@@ -36,7 +36,7 @@ Triggered when the Work Scheduler task starts.
## WorkSchedulerExtensionAbility.onWorkStop
onWorkStop(work: workScheduler.WorkInfo)
onWorkStop(work: workScheduler.WorkInfo): void
Triggered when the Work Scheduler task stops.
......
......@@ -7,7 +7,7 @@
## Modules to Import
```js
import distributedObject from '@ohos.data.distributedDataObject'
import distributedObject from '@ohos.data.distributedDataObject';
```
......@@ -27,9 +27,9 @@ Creates a distributed data object.
| source | object | Yes| Attribute of the distributed data object to create.|
**Return Value**
| Type| Description|
| -------- | -------- |
| [DistributedObject](#distributedobject) | Distributed data object created.|
| Type| Description|
| -------- | -------- |
| [DistributedObject](#distributedobject) | Distributed data object created.|
**Example**
```js
......@@ -171,8 +171,6 @@ Subscribes to the status changes (online or offline) of this distributed data ob
| type | string | Yes| Event type to subscribe to. The value is "status", which indicates the status (online or offline) change events.|
| callback | Callback<{ sessionId: string, networkId: string, status: 'online' \| 'offline' }> | Yes| Callback used to return the online or offline status.<br>**sessionId** indicates the session ID of the distributed data object.<br>**networkId** indicates the network ID of the device.<br>**status** indicates the status, which can be online or offline.|
**Example**
```js
import distributedObject from '@ohos.data.distributedDataObject'
......
......@@ -8,7 +8,7 @@
You need to use [RdbStore.query()](js-apis-data-rdb.md#query) to obtain the **resultSet** object.
```
```js
import dataRdb from '@ohos.data.rdb';
let predicates = new dataRdb.RdbPredicates("EMPLOYEE")
predicates.equalTo("AGE", 18)
......@@ -18,10 +18,6 @@ promise.then((resultSet) => {
console.log(TAG + "resultSet columnCount:" + resultSet.columnCount);})
```
## ResultSet
Provides methods to access the result set, which is obtained by querying the relational database (RDB) store.
......@@ -52,18 +48,18 @@ Obtains the column index based on the column name.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnName | string | Yes| Column name specified.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| number | Index of the column obtained.|
- Example
```
**Example**
```js
resultSet.goToFirstRow()
const id = resultSet.getLong(resultSet.getColumnIndex("ID"))
const name = resultSet.getString(resultSet.getColumnIndex("NAME"))
......@@ -80,18 +76,18 @@ Obtains the column name based on the column index.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Column index specified.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| string | Column name obtained.|
- Example
```
**Example**
```js
const id = resultSet.getColumnName(0)
const name = resultSet.getColumnName(1)
const age = resultSet.getColumnName(2)
......@@ -106,18 +102,18 @@ Moves the cursor to the row based on the specified offset.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| offset | number | Yes| Offset relative to the current position.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgoto = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygoto = rdbStore.query(predicatesgoto, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoto.then((resultSet) {
......@@ -137,18 +133,18 @@ Moves the cursor to the specified row in the result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| position | number | Yes| Position to which the cursor is to be moved.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgotorow = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygotorow = rdbStore.query(predicatesgotorow, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygotorow.then((resultSet) {
......@@ -169,13 +165,13 @@ Moves the cursor to the first row of the result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgoFirst = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygoFirst = rdbStore.query(predicatesgoFirst, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoFirst.then((resultSet) {
......@@ -195,13 +191,13 @@ Moves the cursor to the last row of the result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgoLast = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygoLast = rdbStore.query(predicatesgoLast, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoLast.then((resultSet) {
......@@ -221,13 +217,13 @@ Moves the cursor to the next row in the result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgoNext = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygoNext = rdbStore.query(predicatesgoNext, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoNext.then((resultSet) {
......@@ -247,13 +243,13 @@ Moves the cursor to the previous row in the result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the operation is successful; returns **false** otherwise.|
- Example
```
**Example**
```js
let predicatesgoPrev = new dataRdb.RdbPredicates("EMPLOYEE")
let promisequerygoPrev = rdbStore.query(predicatesgoPrev, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoPrev.then((resultSet) {
......@@ -273,18 +269,18 @@ Obtains the value in the specified column in the current row as a byte array.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Index of the specified column, starting from 0.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| Uint8Array | Value in the specified column as a byte array.|
- Example
```
**Example**
```js
const codes = resultSet.getBlob(resultSet.getColumnIndex("CODES"))
```
......@@ -297,18 +293,18 @@ Obtains the value in the specified column in the current row as a string.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Index of the specified column, starting from 0.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| string | Value in the specified column as a string.|
- Example
```
**Example**
```js
const name = resultSet.getString(resultSet.getColumnIndex("NAME"))
```
......@@ -321,18 +317,18 @@ Obtains the value in the specified column in the current row as a Long.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Index of the specified column, starting from 0.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| number | Value in the specified column as a Long.|
- Example
```
**Example**
```js
const age = resultSet.getLong(resultSet.getColumnIndex("AGE"))
```
......@@ -345,18 +341,18 @@ Obtains the value in the specified column in the current row as a double.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Index of the specified column, starting from 0.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| number | Value in the specified column as a double.|
- Example
```
**Example**
```js
const salary = resultSet.getDouble(resultSet.getColumnIndex("SALARY"))
```
......@@ -369,18 +365,18 @@ Checks whether the value in the specified column of the current row is null.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Parameters
**Parameters**
| Name| Type| Mandatory| Description|
| -------- | -------- | -------- | -------- |
| columnIndex | number | Yes| Index of the specified column, starting from 0.|
- Return value
**Return value**
| Type| Description|
| -------- | -------- |
| boolean | Returns **true** if the value is null; returns **false** otherwise.|
- Example
```
**Example**
```js
const isColumnNull = resultSet.isColumnNull(resultSet.getColumnIndex("CODES"))
```
......@@ -393,13 +389,13 @@ Closes this result set.
**System capability**: SystemCapability.DistributedDataManager.RelationalStore.Core
- Example
```
let predicatesclose = new dataRdb.RdbPredicates("EMPLOYEE")
let predicatesclose = rdbStore.query(predicatesclose, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promisequerygoPrev.then((resultSet) {
**Example**
```js
let predicatesClose = new dataRdb.RdbPredicates("EMPLOYEE")
let promiseClose = rdbStore.query(predicatesClose, ["ID", "NAME", "AGE", "SALARY", "CODES"])
promiseClose.then((resultSet) {
resultSet.close()
}).catch((err) => {
console.log('query failed')
console.log('Failed to close resultset')
})
```
......@@ -3,7 +3,7 @@
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
>
> - The initial APIs of this module are supported since API version 8. Newly added APIs will be marked with a superscript to indicate their earliest API version.
> - The APIs of this module are system APIs and cannot be called by third-party applications.
> - API version 9 is a canary release for trial use. The APIs of this version may be unstable.
## Modules to Import
......@@ -15,7 +15,7 @@ import storagestatistics from "@ohos.storageStatistics";
getTotalSizeOfVolume(volumeUuid: string): Promise&lt;number&gt;
Asynchronously obtains the total space of the specified volume. This method uses a promise to return the result.
Asynchronously obtains the total space of the specified volume. This API uses a promise to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -46,7 +46,7 @@ Asynchronously obtains the total space of the specified volume. This method uses
getTotalSizeOfVolume(volumeUuid: string, callback:AsyncCallback&lt;number&gt;):void
Asynchronously obtains the total space of the specified volume. This method uses a callback to return the result.
Asynchronously obtains the total space of the specified volume. This API uses a callback to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -62,7 +62,7 @@ Asynchronously obtains the total space of the specified volume. This method uses
```js
let uuid = "";
storagestatistics.getTotalSizeOfVolume(uuid, function(error, number){
// Do something
// Do something.
console.info("getTotalSizeOfVolume successfully:"+ number);
});
```
......@@ -73,7 +73,7 @@ Asynchronously obtains the total space of the specified volume. This method uses
getFreeSizeOfVolume(volumeUuid: string): Promise&lt;number&gt;
Asynchronously obtains the available space of the specified volume. This method uses a promise to return the result.
Asynchronously obtains the available space of the specified volume. This API uses a promise to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -105,7 +105,7 @@ Asynchronously obtains the available space of the specified volume. This method
getFreeSizeOfVolume(volumeUuid: string, callback:AsyncCallback&lt;number&gt;):void
Asynchronously obtains the available space of the specified volume. This method uses a callback to return the result.
Asynchronously obtains the available space of the specified volume. This API uses a callback to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -121,7 +121,7 @@ Asynchronously obtains the available space of the specified volume. This method
```js
let uuid = "";
storagestatistics.getFreeSizeOfVolume(uuid, function(error, number){
// Do something
// Do something.
console.info("getFreeSizeOfVolume successfully:"+ number);
});
```
......@@ -130,7 +130,7 @@ Asynchronously obtains the available space of the specified volume. This method
getBundleStats(packageName: string): Promise&lt;BundleStats&gt;
Obtains the bundle status. This method uses a promise to return the result.
Asynchronously obtains app information. This API uses a promise to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -144,7 +144,7 @@ Obtains the bundle status. This method uses a promise to return the result.
| Type | Description |
| ------------------------------------------ | -------------------------- |
| Promise&lt;[Bundlestats](#bundlestats)&gt; | Promise used to return the bundle status on the volume.|
| Promise&lt;[Bundlestats](#bundlestats)&gt; | Promise used to return the app information.|
- Example
......@@ -161,7 +161,7 @@ Obtains the bundle status. This method uses a promise to return the result.
getBundleStats(packageName: string, callback: AsyncCallback&lt;BundleStats&gt;): void
Obtains the bundle status. This method uses an asynchronous callback to return the result.
Asynchronously obtains app information. This API uses a callback to return the result.
**System capability**: SystemCapability.FileManagement.StorageService.SpatialStatistics
......@@ -170,14 +170,14 @@ Obtains the bundle status. This method uses an asynchronous callback to return t
| Name | Type | Mandatory| Description |
| -------- | --------------------------------------------------------- | ---- | ------------------------------------ |
| packageName | string | Yes | Bundle name of the app.|
| callback | callback:AsyncCallback&lt;[Bundlestats](#bundlestats)&gt; | Yes | Callback invoked to return the bundle status on the volume.|
| callback | callback:AsyncCallback&lt;[Bundlestats](#bundlestats)&gt; | Yes | Callback invoked to return the app information.|
- Example
```js
let packageName = "";
storagestatistics.getBundleStats(packageName, function(error, BundleStats){
// Do something
// Do something.
console.info("getBundleStats successfully:"+ JSON.stringify(BundleStats));
});
```
......@@ -191,5 +191,5 @@ Obtains the bundle status. This method uses an asynchronous callback to return t
| Name | Type | Description |
| --------- | ------ | -------------- |
| appSize<sup>9+</sup> | number | Size of the app. |
| cacheSize<sup>9+</sup> | number | Size of the cached data. |
| cacheSize<sup>9+</sup> | number | Cache size of the app. |
| dataSize<sup>9+</sup> | number | Total data size of the app.|
......@@ -2,8 +2,8 @@
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**<br/>
>
> - The initial APIs of this module are supported since API version 9. Newly added APIs will be marked with a superscript to indicate their earliest API version.
> - The APIs of this module are system APIs and cannot be called by third-party applications.
> - The initial APIs of this module are supported since API version 9.
> - API version 9 is a canary release for trial use. The APIs of this version may be unstable.
## Modules to Import
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册