openharmony-arkts-utils
npx skills add https://github.com/mengfei0053/skills --skill openharmony-arkts-utils
Agent 安装分布
Skill 文档
OpenHarmony ArkTS å·¥å ·åºå¿«éåè
OpenHarmony ArkTSå·¥å ·åºãå¹¶ååè¿è¡æ¶ç¹æ§çå¿«éæ¥æ¾æåã
æ¦è¿°
ArkTSæä¾å ¨é¢çå·¥å ·åºï¼å æ¬å¼æ¥å¹¶åãå¤çº¿ç¨ï¼TaskPool/Workerï¼ãæ°æ®ç»æï¼XML/Buffer/JSON/容å¨ï¼ãè¿è¡æ¶ç¹æ§åæå»ºå·¥å ·ã
宿¹ææ¡£ï¼ https://docs.openharmony.cn/
ð è¯¦ç» API åèæä»¶
æ¬æè½æä»¶æä¾æ¦å¿µæåå常ç¨ç¤ºä¾ãè¯¦ç» API ç¾åå宿´ç¤ºä¾è¯·åè refs/ æä»¶å¤¹ï¼
| æä»¶ | å 容 | éç¨åºæ¯ |
|---|---|---|
refs/taskpool.md |
TaskPool 宿´ API | TaskãTaskGroupãä¼å 级ãå»¶æ¶æ§è¡ |
refs/worker.md |
Worker 宿´ API | ThreadWorkerãæ¶æ¯éä¿¡ãçå½å¨æ |
refs/collections.md |
å ±äº«å®¹å¨ API | collections.Array/Map/Set (跨线ç¨) |
refs/utils.md |
ArkTSUtils API | AsyncLockãASONãSendableå·¥å · |
refs/buffer.md |
Buffer API | äºè¿å¶æ°æ®å¤çãç¼ç è½¬æ¢ |
refs/xml.md |
XML API | XmlSerializerãXmlPullParser |
refs/containers.md |
线æ§/é线æ§å®¹å¨ API | ArrayListãHashMap çæ®éå®¹å¨ |
refs/error-codes.md |
é误ç éæ¥è¡¨ | 10200001-10200301 é误å¤ç |
弿¥å¹¶å (Promise & async/await)
Promise
åºæ¬ç¨æ³ï¼
const promise: Promise<number> = new Promise((resolve: Function, reject: Function) => {
setTimeout(() => {
const randomNumber: number = Math.random();
if (randomNumber > 0.5) {
resolve(randomNumber);
} else {
reject(new Error('Random number is too small'));
}
}, 1000);
})
// å¤çç»æ
promise.then((result: number) => {
console.info(`The number for success is ${result}`);
}).catch((error: Error) => {
console.error(error.message);
}).finally(() => {
console.info('finally complete');
})
使ç¨åºæ¯ï¼ I/Oæä½ï¼ç½ç»ãæä»¶ï¼ã宿¶å¨ãè½»é级éé»å¡ä»»å¡
说æï¼ å½Promise被reject䏿ªéè¿catchæ¹æ³å¤çæ¶ï¼ä¼è§¦åglobalUnhandledRejectionDetectedäºä»¶ãå¯ä½¿ç¨
errorManager.on('globalUnhandledRejectionDetected')æ¥å£çå¬è¯¥äºä»¶ï¼ä»¥å ¨å±æè·æªå¤ççPromise rejectã
async/await
async function myAsyncFunction(): Promise<string> {
try {
const result: string = await new Promise((resolve: Function) => {
resolve('Hello, world!');
});
console.info(result); // è¾åºï¼ Hello, world!
return result;
} catch (e) {
console.error(`Get exception: ${e}`);
}
}
myAsyncFunction();
ä¼å¿ï¼ 以忥æ¹å¼ç¼å弿¥ä»£ç ï¼éè¿try-catchå®ç°æ´å¥½çé误å¤ç
说æï¼ çå¾ å¼æ¥æä½æ¶ï¼éå°æä½å å¨async彿°ä¸ï¼å¹¶æé await使ç¨ï¼ä¸awaitå ³é®ååªå¨async彿°å ææã
å¤çº¿ç¨ – TaskPool
TaskPoolèªå¨ç®¡ççº¿ç¨æ± ï¼æ éçå½å¨æç®¡çãç³»ç»é»è®¤å¯å¨ä¸ä¸ªä»»å¡å·¥ä½çº¿ç¨ï¼ä»»å¡å¤æ¶ä¼èªå¨æ©å®¹ãå·¥ä½çº¿ç¨æ°éä¸éç±è®¾å¤çç©çæ ¸æ°å³å®ã
åºæ¬TaskPool使ç¨
import { taskpool } from '@kit.ArkTS';
@Concurrent
function add(num1: number, num2: number): number {
return num1 + num2;
}
async function concurrentFunc(): Promise<void> {
const task: taskpool.Task = new taskpool.Task(add, 1, 2);
console.info(`taskpool res is: ${await taskpool.execute(task)}`); // è¾åºç»æï¼taskpool res is: 3
}
TaskGroupæ¹éæ§è¡
@Concurrent
function processData(data: number): number {
return data * 2;
}
function executeTaskGroup() {
const group = new taskpool.TaskGroup();
group.addTask(processData, 10);
group.addTask(processData, 20);
group.addTask(processData, 30);
taskpool.execute(group).then((results: number[]) => {
console.info(`Group results: ${results}`); // [20, 40, 60]
});
}
ä»»å¡é ç½®
const task = new taskpool.Task(computeTask, 1000);
// 设置ä¼å
级
task.priority = taskpool.Priority.HIGH; // HIGH, MEDIUM, LOW, IDLE
// 设置ArrayBuffer转移å表ï¼é¶æ·è´ï¼ç§»å¨æææï¼
task.setTransferList([buffer]);
// 设置ArrayBufferæ·è´å表ï¼å¤å¶æ°æ®ï¼
task.setCloneList([buffer]);
// æå®ä¼å
级æ§è¡
taskpool.execute(task, taskpool.Priority.HIGH);
弿¥éåæ§å¶å¹¶å度
import { taskpool } from '@kit.ArkTS';
// åå»ºå¼æ¥éåï¼åç§°ãå¹¶åæ°ãéå大å°
const asyncRunner = new taskpool.AsyncRunner("camera", 5, 5);
@Concurrent
function collectFrame(): void {
// ééå¸§æ°æ®
}
for (let i = 0; i < 20; i++) {
const task = new taskpool.Task(collectFrame);
asyncRunner.execute(task);
}
ä»»å¡åæ¶
@Sendable
class TaskManager {
taskId: number = 0;
setTaskId(id: number) { this.taskId = id; }
getTaskId(): number { return this.taskId; }
}
@Concurrent
function cancelTask(manager: TaskManager) {
taskpool.cancel(manager.getTaskId());
}
const task = new taskpool.Task(delayedTask);
taskpool.executeDelayed(2000, task);
const manager = new TaskManager();
manager.setTaskId(task.taskId);
taskpool.execute(cancelTask, manager);
å»¶æ¶æ§è¡ä»»å¡
@Concurrent
function delayedTask(): void {
console.info('Delayed task executed');
}
// å»¶æ¶2ç§æ§è¡
const task = new taskpool.Task(delayedTask);
taskpool.executeDelayed(2000, task);
@Concurrentè£ é¥°å¨è§è
| è£ é¥°å¨åæ° | æ | | è£ é¥°ç彿°ç±»å | async彿°ææ®é彿°ãç¦æ¢generatorãç®å¤´å½æ°ãç±»æ¹æ³ã䏿¯æç±»æå彿°æè å¿å彿° | | è£ é¥°ç彿°å çåéç±»å | å 许使ç¨å±é¨åéãå ¥ååéè¿importå¼å ¥çåéï¼ç¦æ¢ä½¿ç¨éå åé | | 使ç¨åºæ¯éå¶ | ä» æ¯æå¨Stage模åçå·¥ç¨ä¸ä½¿ç¨ï¼ä» æ¯æå¨.etsæä»¶ä¸ä½¿ç¨ |
注æï¼ @Concurrentæ è®°ç彿°ä¸è½è®¿é®éå ï¼å æ¤å½æ°å é¨ä¸è½è°ç¨å½åæä»¶çå ¶ä»å½æ°ã
TaskPool vs Worker 对æ¯
| ç¹æ§ | TaskPool | Worker |
|---|---|---|
| 使ç¨åºæ¯ | çæç¬ç«ä»»å¡ | é¿æåå°ä»»å¡ |
| 线ç¨ç®¡ç | èªå¨ | æå¨ï¼çå½å¨æç®¡çï¼ |
| 任塿¶é¿ | < 3åéï¼ä¸å«å¼æ¥æä½èæ¶ï¼ | æ éå¶ |
| 线ç¨åé | ç³»ç»ç®¡ç | æ¾å¼æå® |
| ä¼å 级æ§å¶ | æ¯æ | API 18+æ¯æ |
| ä»»å¡åæ¶ | æ¯æ | 䏿¯æ |
| 线ç¨å¤ç¨ | æ¯æ | 䏿¯æ |
| ä»»å¡å»¶æ¶æ§è¡ | æ¯æ | 䏿¯æ |
| ä»»å¡ä¾èµå ³ç³» | æ¯æ | 䏿¯æ |
| 串è¡éå | æ¯æ | 䏿¯æ |
| ä»»å¡ç» | æ¯æ | 䏿¯æ |
| å¨æä»»å¡ | æ¯æ | 䏿¯æ |
| 弿¥éå | æ¯æ | 䏿¯æ |
TaskPool约æå注æäºé¡¹
- ä»»å¡å¿
须使ç¨
@Concurrentè£ é¥°å¨ - 任塿§è¡æ¶é¿ä¸è½è¶ è¿3åéï¼ä¸å å«Promiseæasync/await弿¥è°ç¨çèæ¶ï¼
- åºååä¼ è¾çæ°æ®ééå¶ä¸º16MB
- åæ°å¿ é¡»æ»¡è¶³åºå忝æçç±»åï¼ä¸æ¯æ@State/@Prop/@Linkçè£ é¥°å¨ä¿®é¥°çå¤æç±»å
- ArrayBufferåæ°å¨TaskPoolä¸é»è®¤è½¬ç§»ï¼é夿¬¡ä½¿ç¨æ¶éè¿setCloneList设置æ·è´
- å·¥ä½çº¿ç¨åªè½ä½¿ç¨çº¿ç¨å®å ¨çåºï¼ä¸è½ä½¿ç¨UIç¸å ³çé线ç¨å®å ¨åº
- 䏿¯æå¨TaskPoolå·¥ä½çº¿ç¨ä¸ä½¿ç¨AppStorage
- Promise䏿¯æè·¨çº¿ç¨ä¼ é
- PriorityçIDLEä¼å 级ç¨äºæ è®°éè¦å¨åå°è¿è¡çèæ¶ä»»å¡ï¼åªå¨ææçº¿ç¨é½ç©ºé²æ¶è§¦åæ§è¡
ð è¯¦ç» API åè:
refs/taskpool.mdâ TaskãTaskGroupãä¼å 级ãå»¶æ¶æ§è¡ç宿´ API ç¾åå示ä¾
å¤çº¿ç¨ – Worker
Workeræä¾ä¸ç¨çé¿æåå°çº¿ç¨ãå个è¿ç¨ä¸ï¼æå¤æ¯æåæ¶å¼å¯64个Worker线ç¨ï¼å®é æ°éç±è¿ç¨å åå³å®ã
åºæ¬Worker使ç¨
// 主线ç¨
import { worker } from '@kit.ArkTS';
const workerInstance = new worker.ThreadWorker('entry/ets/workers/Worker.ets');
// åéæ¶æ¯
workerInstance.postMessage('hello world');
// æ¥æ¶æ¶æ¯
workerInstance.onmessage = (event: MessageEvents) => {
console.info(`Received: ${event.data}`);
};
// æè·å
¨å±å¼å¸¸ï¼æ¨èï¼
workerInstance.onAllErrors = (error: ErrorEvent) => {
console.error(`Worker error: ${error.message}`);
// å¼å¸¸åWorker线ç¨ç»§ç»è¿è¡
};
// 鿝Worker
workerInstance.terminate();
Workerçº¿ç¨ (Worker.ets):
import { worker } from '@kit.ArkTS';
const workerPort = worker.workerPort;
workerPort.onmessage = (event: MessageEvents) => {
const data = event.data;
// å¤çæ°æ®
workerPort.postMessage({ result: 'done' });
};
Workeré信模å¼
峿¶æ¶æ¯ä¼ éï¼
// ä¸»çº¿ç¨ â Worker
workerInstance.postMessage(message);
// Worker â 主线ç¨
workerPort.postMessage(result);
忥è°ç¨ï¼
// å¨Workerä¸åæ¥è°ç¨ä¸»çº¿ç¨æ¹æ³
const result = workerPort.syncCall(method, params);
Workerçå½å¨æç®¡ç
// å建Worker
const workerInstance = new worker.ThreadWorker('entry/ets/workers/Worker.ets', {
type: 'classic' // æ 'module' ç±»å
});
// çå¬éåºäºä»¶
workerInstance.onexit = () => {
console.info('Worker terminated');
isTerminate = true;
};
// 鿝Worker
workerInstance.terminate();
// çå¾
Workerå®å
¨éåº
while (!isTerminate) {
await promiseCase();
}
Workeré误å¤ç
// æ¨è使ç¨onAllErrorsæè·ææå¼å¸¸
workerInstance.onAllErrors = (error: ErrorEvent) => {
console.error(`Type: ${error.type}, Message: ${error.message}`);
// å¼å¸¸åWorker线ç¨ç»§ç»è¿è¡
};
// onerrorä»
æè·onmessageåè°ä¸ç忥å¼å¸¸
workerInstance.onerror = (error: ErrorEvent) => {
console.error(`Error: ${error.message}`);
// å¼å¸¸åWorker线ç¨è¿å
¥éæ¯æµç¨
};
Worker vs TaskPool éæ©
æ¨è使ç¨TaskPoolçåºæ¯ï¼
- è¿è¡æ¶é´ä¸è¶ è¿3åéçç¬ç«ä»»å¡
- CPUå¯éåä»»å¡ï¼å¾åå¤çãæ°æ®åæï¼
- I/Oå¯éåä»»å¡ï¼æä»¶è¯»åãç½ç»è¯·æ±ï¼
- éè¦è®¾ç½®ä¼å 级çä»»å¡
- éè¦é¢ç¹åæ¶çä»»å¡
- 大éæè°åº¦ç¹åæ£çä»»å¡
æ¨è使ç¨Workerçåºæ¯ï¼
- è¿è¡æ¶é´è¶ è¿3åéçé¿æ¶ä»»å¡
- æå ³èçä¸ç³»å忥任å¡ï¼ä½¿ç¨åä¸å¥æï¼
- éè¦æå®è¿è¡çº¿ç¨çä»»å¡
ð è¯¦ç» API åè:
refs/worker.mdâ ThreadWorkerãæ¶æ¯éä¿¡ãçå½å¨æç®¡çç宿´ API
Sendable – 跨线ç¨å ±äº«å¯¹è±¡
Sendableå¯ç¨å®å ¨ç对象跨线ç¨å ±äº«ãSendable对象åé å¨å ±äº«å ï¼SharedHeapï¼ä¸ï¼å®ç°è·¨å¹¶åå®ä¾çå åå ±äº«ã
åºæ¬@Sendable使ç¨
@Sendable
class SendableTestClass {
desc: string = "sendable: this is SendableTestClass ";
num: number = 5;
printName() {
console.info("sendable: SendableTestClass desc is: " + this.desc);
}
getNum(): number {
return this.num;
}
}
// å¯ç´æ¥ä¼ éç»TaskPool/Workerï¼æ éæ·è´
const data = new SendableTestClass();
taskpool.execute(task, data);
@Sendable彿°ä½¿ç¨
@Sendable
type SendableFuncType = () => void;
@Sendable
function TopLevelSendableFunction() {
console.info("Top level sendable function");
}
@Sendable
class SendableTestClass {
callback: SendableFuncType;
constructor(func: SendableFuncType) {
this.callback = func;
}
CallSendableFunc() {
TopLevelSendableFunction();
}
}
@Sendableè£ é¥°å¨è§è
| è£ é¥°å¨åæ° | æ | | 使ç¨åºæ¯éå¶ | ä» æ¯æå¨Stage模åç.etsæä»¶ä¸ä½¿ç¨ | | è£ é¥°ç类继æ¿å ³ç³»éå¶ | Sendable classåªè½ç»§æ¿Sendable classï¼æ®éclassä¸å¯ç»§æ¿Sendable class | | è£ é¥°ç对象å ç屿§ç±»åéå¶ | æ¯æstringãnumberãbooleanãbigintãnullãundefinedãSendable classãcollections容å¨éãArkTSUtils.locks.AsyncLockçãç¦æ¢ä½¿ç¨éå åéï¼é¡¶å±Sendableç±»å彿°é¤å¤ï¼ | | è£ é¥°ç对象å ç屿§çå ¶ä»éå¶ | æå屿§å¿ é¡»æ¾å¼åå§åï¼ä¸è½ä½¿ç¨æå¹å·ã䏿¯æå¢å æå é¤å±æ§ï¼å 许修æ¹å±æ§ï¼ä¿®æ¹ååç±»åå¿ é¡»ä¸è´ | | éç¨åºæ¯ | 1. å¨TaskPoolæWorkerä¸ä½¿ç¨ç±»æ¹æ³æSendable彿°2. ä¼ è¾å¯¹è±¡æ°æ®éè¾å¤§çåºæ¯ï¼100KBæ°æ®æçæå约20åï¼1Mæ°æ®æçæå约100åï¼ |
Sendableæ¯æçæ°æ®ç±»å
åºæ¬æ°æ®ç±»åï¼
- booleanãnumberãstringãbigintãnullãundefined
容å¨ç±»åï¼éæ¾å¼å¼å ¥@arkts.collectionsï¼ï¼
- collections.Arrayãcollections.Mapãcollections.Set
- collections.TypedArrayï¼Int8ArrayãUint8Arrayçï¼
- collections.ArrayBuffer
å¹¶åå·¥å ·ç±»åï¼éæ¾å¼å¼å ¥@arkts.utilsï¼ï¼
- ArkTSUtils.locks.AsyncLock
- ArkTSUtils.locks.ConditionVariable
- ArkTSUtils.SendableLruCache
å¤åç±»åï¼
- æ æ³¨äº@Sendableè£ é¥°å¨çclass
- æ æ³¨äº@Sendableè£ é¥°å¨çfunction
- ç»§æ¿äºISendableçinterface
- å ç´ å为Sendableç±»åçunion type
注æï¼ JSå 置对象å¨å¹¶åå®ä¾é´ä¼ éæ¶éµå¾ªç»æåå éç®æ³ï¼è·¨çº¿ç¨è¡ä¸ºæ¯æ·è´ä¼ éã对象åé¢éåæ°ç»åé¢éä¹ä¸æ¯Sendableç±»åã
å ±äº«å®¹å¨
import { collections, ArkTSUtils, taskpool } from '@kit.ArkTS';
// å
񄧮Array
const arr = collections.Array.create<number>(100, 0);
// å
񄧮Map
const map = new collections.Map<string, number>();
map.set('key1', 100);
// é
å弿¥é使ç¨ï¼é²æ¢å¹¶åä¿®æ¹ï¼
@Concurrent
async function add(arr: collections.Array<number>, lock: ArkTSUtils.locks.AsyncLock) {
await lock.lockAsync(() => {
arr[0]++;
})
}
说æï¼ ArkTSå ±äº«å®¹å¨ä¸æ¯çº¿ç¨å®å ¨çï¼å é¨ä½¿ç¨äºfail-fastæºå¶ãå¨å¤çº¿ç¨åºæ¯ä¸ä¿®æ¹å®¹å¨å 屿§æ¶ï¼éè¦ä½¿ç¨ArkTSæä¾ç弿¥éæºå¶ä¿è¯å®å ¨è®¿é®ã
ð è¯¦ç» API åè:
refs/collections.mdâ collections.Array/Map/Set 跨线ç¨å ±äº«å®¹å¨å®æ´ API
弿¥é (AsyncLock)
import { ArkTSUtils, taskpool } from '@kit.ArkTS';
@Sendable
export class A {
private count_: number = 0;
lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();
public getCount(): Promise<number> {
return this.lock_.lockAsync(() => {
return this.count_;
})
}
public async increaseCount() {
await this.lock_.lockAsync(() => {
this.count_++;
})
}
}
@Concurrent
async function printCount(a: A) {
a.increaseCount();
console.info("InputModule: count is:" + await a.getCount());
}
æ¡ä»¶åé (ConditionVariable)
import { ArkTSUtils } from '@kit.ArkTS';
const conditionVariable: ArkTSUtils.locks.ConditionVariable = new ArkTSUtils.locks.ConditionVariable();
// çå¾
æ¡ä»¶ï¼æ éçå¾
ï¼
await conditionVariable.wait();
// çå¾
æ¡ä»¶ï¼è¶
æ¶çå¾
ï¼
await conditionVariable.waitFor(timeout);
// å¤éä¸ä¸ªçå¾
线ç¨
conditionVariable.notifyOne();
// å¤éææçå¾
线ç¨
conditionVariable.notifyAll();
å ±äº«æ¨¡å
// sharedModule.ets
"use shared"
@Sendable
class GlobalCounter {
private count_: number = 0;
lock_: ArkTSUtils.locks.AsyncLock = new ArkTSUtils.locks.AsyncLock();
async increment(): Promise<number> {
return this.lock_.lockAsync(() => {
return ++this.count_;
});
}
}
export let globalCounter = new GlobalCounter();
å ±äº«æ¨¡å约æï¼
- å ±äº«æ¨¡ååªæ¯æ.etsæä»¶
- å ±äº«æ¨¡åå ä¸å 许使ç¨side-effects-import
- å ±äº«æ¨¡å导åºçææå¯¹è±¡å¿ é¡»æ¯å¯å ±äº«çSendableç±»å
- å ±äº«æ¨¡å䏿¯ære-exportåæ³
ð è¯¦ç» API åè:
refs/utils.mdâ AsyncLockãConditionVariableãASONãLruCache 宿´ API
容å¨åº
ArkTSå ±äº«å®¹å¨ (@arkts.collections)
| å®¹å¨ | ç¨é | ç¹æ§ |
|---|---|---|
| collections.Array | 卿æ°ç»ï¼å¼ç¨ä¼ éï¼è·¨çº¿ç¨é«æ | æ¯æpushãpopãspliceãforEachç |
| collections.Map | é®å¼å¯¹éåï¼å¼ç¨ä¼ é | æ¯æsetãgetãhasãdeleteç |
| collections.Set | å¼éåï¼å¼ç¨ä¼ é | æ¯æaddãhasãdeleteç |
| collections.TypedArray | ç±»ååæ°ç»ï¼Int8ArrayãUint8Arrayçï¼ | åºå®ç±»åï¼é«æ§è½ |
| collections.ArrayBuffer | æ°ç»ç¼å²åº | æ¯æsliceãbyteLength |
注æï¼ ArkTSå ±äº«å®¹å¨éç¨å¼ç¨ä¼ éæ¹å¼è·¨çº¿ç¨ä¼ éï¼ä¸åç容å¨ç¸æ¯æçæ´é«ã妿éè¦è·¨çº¿ç¨ä¼ è¾å¤§éæ°æ®ï¼å»ºè®®ä½¿ç¨ArkTSå ±äº«å®¹å¨ã
线æ§å®¹å¨ (@arkts.collections)
| å®¹å¨ | ç¨é | å¤æåº¦ |
|---|---|---|
| ArrayList | 卿æ°ç»ï¼é¢ç¹è¯»å | O(1) è®¿é® |
| Vector | 卿æ°ç»ï¼åºå®ç±»å | O(1) 访é®ï¼å·²åºå¼ï¼æ¨èArrayListï¼ |
| LinkedList | ååé¾è¡¨ï¼é¢ç¹æå ¥å é¤ | O(1) æå ¥ |
| Deque | å端éåï¼å¤´å°¾æä½ | O(1) 头尾 |
| List | ååé¾è¡¨ï¼é¢ç¹æå ¥å é¤ | O(1) æå ¥ |
| Queue | éåï¼å è¿å åº | O(1) å ¥é/åºé |
| Stack | æ ï¼å è¿ååº | O(1) push/pop |
ArrayList示ä¾ï¼
import { collections } from '@kit.ArkTS';
const list = new collections.ArrayList<string>();
list.add('item1');
list.add('item2');
list.has('item1'); // true
list.remove(0);
const size = list.size;
é线æ§å®¹å¨ (@arkts.collections)
| å®¹å¨ | ç¨é | é¡ºåº |
|---|---|---|
| HashMap | å叿 å°ï¼å¿«éåå | æ åº |
| HashSet | åå¸éåï¼å¯ä¸å¼ | æ åº |
| TreeMap | æåºæ å°ï¼æ¯æèªå®ä¹æåº | æé®æåº |
| TreeSet | æåºéåï¼æ¯æèªå®ä¹æåº | æå¼æåº |
| LightWeightMap | è½»é级æ å°ï¼å åå ç¨å° | æ åº |
| LightWeightSet | è½»é级éåï¼å åå ç¨å° | æ åº |
| PlainArray | è½»é级æ°ç»ï¼é®ä¸ºnumberç±»å | – |
HashMap示ä¾ï¼
import { collections } from '@kit.ArkTS';
const map = new collections.HashMap<string, number>();
map.set('key1', 100);
map.set('key2', 200);
map.has('key1'); // true
const value = map.get('key1'); // 100
çº¿æ§ vs é线æ§å®¹å¨
- 线æ§å®¹å¨ï¼æé¡ºåºè®¿é®ï¼åºå±åºäºæ°ç»æé¾è¡¨å®ç°ãä¼åæ°æ®è®¿é®é度ï¼éåé¢ç¹è¯»åå ç´ æé¡ºåºæä½
- é线æ§å®¹å¨ï¼å¿«éæ¥æ¾ï¼åºå±åºäºåå¸æçº¢é»æ å®ç°ãæ¯æå¿«éæ¥æ¾ï¼key/valueç±»å符åECMAæ å
ð è¯¦ç» API åè:
refs/containers.mdâ ArrayListãHashMapãTreeMap çæ®é容å¨å®æ´ API
XMLå¤ç
XMLçæ
import { xml, util } from '@kit.ArkTS';
// æ¹å¼1ï¼ä½¿ç¨XmlSerializerï¼åºå®ç¼å²åºï¼
let arrayBuffer: ArrayBuffer = new ArrayBuffer(2048);
let serializer: xml.XmlSerializer = new xml.XmlSerializer(arrayBuffer);
serializer.setDeclaration(); // åå
¥XML声æ
serializer.startElement('bookstore');
serializer.startElement('book');
serializer.setAttributes('category', 'COOKING');
serializer.startElement('title');
serializer.setAttributes('lang', 'en');
serializer.setText('Everyday');
serializer.endElement();
serializer.startElement('author');
serializer.setText('Giana');
serializer.endElement();
serializer.endElement();
serializer.endElement();
// æ¹å¼2ï¼ä½¿ç¨XmlDynamicSerializerï¼å¨ææ©å®¹ï¼
let DySerializer = new xml.XmlDynamicSerializer('utf-8');
DySerializer.setDeclaration();
DySerializer.startElement('bookstore');
// ... æ·»å å
ç´
let arrayBuffer = DySerializer.getOutput();
// è§£ç è¾åº
let uint8Array: Uint8Array = new Uint8Array(arrayBuffer);
let result: string = util.TextDecoder.create().decodeToString(uint8Array);
console.info(result);
XMLè§£æ
import { xml } from '@kit.ArkTS';
const xmlString = '<note><to>User</to><from>System</from></note>';
// 使ç¨XmlPullParserè§£æ
let parser = new xml.XmlPullParser(xmlString);
parser.parseXml({
supportDoctype: true,
ignoreNameSpace: true,
tagValueCallbackFunction: (name, value) => {
console.info(`Tag: ${name}, Value: ${value}`);
}
});
XML转æ¢
import { xml } from '@kit.ArkTS';
// å°XML转æ¢ä¸ºJavaScript对象
const jsonObj = xml.fastConvertToJSObject(xmlString, {
trim: true,
declarationKey: '_declaration',
attributesKey: '_attributes'
});
// 转æ¢ç»æç¤ºä¾ï¼
// {
// "_declaration": {"_attributes": {"version": "1.0", "encoding": "UTF-8"}},
// "note": {
// "_attributes": {"priority": "high"},
// "to": "User",
// "from": "System"
// }
// }
ð è¯¦ç» API åè:
refs/xml.mdâ XmlSerializerãXmlPullParserãXML转æ¢å®æ´ API
Bufferåäºè¿å¶
Buffer
import { buffer } from '@kit.ArkTS';
// å建buffer
const buf = buffer.from('Hello World', 'utf-8');
// åå
¥
buf.writeUInt8(0, 65);
// 读å
const byte = buf.readUInt8(0);
// 转æ¢
const str = buf.toString('utf-8');
const arrayBuffer = buf.buffer;
ArrayBuffer转移/æ·è´
转移ï¼é¶æ·è´ï¼ç§»å¨æææï¼ï¼
task.setTransferList([arrayBuffer]);
// 转移ååå§ArrayBufferå为ä¸å¯ç¨
æ·è´ï¼å¤å¶æ°æ®ï¼ï¼
task.setCloneList([arrayBuffer]);
// æ·è´ååå§ArrayBufferä»å¯ç¨
ð è¯¦ç» API åè:
refs/buffer.mdâ Buffer å建ã读åãç¼ç 转æ¢å®æ´ API
JSONå·¥å ·
import { JSON } from '@kit.ArkTS';
// è§£æï¼æ¯æBigInt模å¼ï¼
let numberText = '{"number": 10, "largeNumber": 112233445566778899}';
// 使ç¨PARSE_AS_BIGINT模å¼è§£æå¤§æ´æ°
let options: JSON.ParseOptions = {
bigIntMode: JSON.BigIntMode.PARSE_AS_BIGINT,
}
let numberObj = JSON.parse(numberText, null, options) as Object;
console.info(typeof (numberObj as object)?.["largeNumber"]); // bigint
// åºååï¼æ¯æBigIntï¼
let bigIntObject = BigInt(112233445566778899n);
let result: string = JSON.stringify(bigIntObject);
console.info(result); // 112233445566778899
// å¸¦æ ¼å¼çåºåå
let obj = { name: "Tom", age: 20 };
let str = JSON.stringify(obj, null, 2);
// æ£æ¥å±æ§
let hasProp = JSON.has(obj, "name"); // true
// å é¤å±æ§
JSON.remove(obj, "age");
JSONæ©å±åºç¹æ§ï¼
- æ¯æBigIntè§£æååºåå
- 循ç¯å¼ç¨æ£æµ
- å¼ºåæ°æ ¡éª
- å¢å¼ºçé误å¤çï¼BusinessErrorï¼
- é¢å¤æ¹æ³ï¼has/removeï¼
è¿è¡æ¶ç¹æ§
å¨æå¯¼å ¥
// 常é卿坼å
¥
import('myhar').then((ns:ESObject) => {
console.info(ns.add(3, 5));
});
// 弿¥å¤ç
async function asyncDynamicImport() {
let ns:ESObject = await import('myhar');
console.info(ns.add(3, 5));
}
// åé卿坼å
¥ï¼éé
ç½®runtimeOnlyï¼
let packageName = 'myhar';
import(packageName).then((ns:ESObject) => {
console.info(ns.add(3, 5));
});
runtimeOnlyé ç½®ï¼ä» åéå¨æå¯¼å ¥éè¦ï¼ï¼
// build-profile.json5
{
"buildOption": {
"arkOptions": {
"runtimeOnly": {
"packages": ["myhar"], // å
¶ä»æ¨¡åå
"sources": ["./src/main/ets/utils/Calc.ets"] // æ¬æ¨¡åæä»¶è·¯å¾
}
}
}
}
æ¯æçå¨æå¯¼å ¥åºæ¯ï¼
- æ¬å°å·¥ç¨æ¨¡åï¼./ã../å¼å¤´çè·¯å¾ï¼
- HSP/HAR模åå
- è¿ç¨HAR模åå
- ohpmå å
- @system.ã@ohos.ã@arkui-x.* API
- libNativeLibrary.so
æå¯¼å ¥
// åºæ¬è¯æ³ï¼API 12+ï¼
import lazy { x } from "mod";
import lazy { x as v } from "mod";
import lazy x from "mod"; // API 18+
import lazy { KitClass } from "@kit.SomeKit"; // API 18+
䏿¯æçè¯æ³ï¼
// 以ä¸åæ³å°å¼èµ·ç¼è¯æ¥é
import lazy * as ns from "mod";
import lazy type { obj } from "./mod";
使ç¨åºæ¯ï¼
- æä»¶å¨å·å¯å¨é¶æ®µæªè¢«å®é è°ç¨
- åå°å·å¯å¨æ¶é´ï¼å»¶è¿æ§è¡å°å®é ä½¿ç¨æ¶
注æï¼ ä¸å»ºè®®ç²ç®å¢å lazyï¼è¿ä¼å¢å ç¼è¯åè¿è¡æ¶çè¯å«å¼éãåç»æ§è¡çå è½½æ¯åæ¥å è½½ï¼å¯è½é»å¡ä»»å¡æ§è¡ã
åçæ¨¡åå è½½
éæå¯¼å ¥ï¼
// å
·å导å
¥
import { add } from 'libentry.so';
// é»è®¤å¯¼å
¥
import entry from 'libentry.so';
entry.add(2, 3);
// å½å空é´å¯¼å
¥
import * as entry from 'libentry.so';
entry.add(2, 3);
å¨æå¯¼å ¥ï¼
import('libentry.so').then((ns:ESObject) => {
ns.default.add(2, 3);
});
async function asyncDynamicImport() {
let ns:ESObject = await import('libentry.so');
ns.default.add(2, 3);
}
模åå¯ä½ç¨ä¼å
é®é¢ä»£ç ï¼
// Bad - 导å
¥æ¶ç«å³æ§è¡
console.log("Module loaded!");
export const data = 1;
// Bad - ç´æ¥ä¿®æ¹å
¨å±
globalThis.someGlobalVar = 100;
// Bad - 导å
¥æ¶ä¿®æ¹AppStorage
AppStorage.setOrCreate("SomeAppStorageVar", 200);
ä¼åæ¹æ¡ï¼
// Good - ç§»é¤é¡¶å±ä»£ç
export const data = 1;
export function initialize() {
console.log("Module loaded!");
}
// Good - å»¶è¿å°éè¦æ¶æ§è¡
export function changeGlobalVar() {
globalThis.someGlobalVar = 100;
}
// Good - æéè°ç¨
export function initializeAppStorage() {
AppStorage.setOrCreate("SomeAppStorageVar", 200);
}
å¹¶åæä½³å®è·µ
ä»»å¡éæ©æå
| åºæ¯ | æ¨èæ¹æ¡ |
|---|---|
| CPUå¯éåçæä»»å¡ | TaskPool |
| I/Oå¯éåæä½ | async/await |
| é¿æåå°ä»»å¡ | Worker |
| ç¬ç«å¹¶è¡ä»»å¡ | TaskGroup |
| 跨线ç¨å ±äº«ç¶æ | Sendable + å®¹å¨ |
| æåºä»»å¡æ§è¡ | TaskPool + ä¼å 级 |
å¸¸è§æ¨¡å¼
å¹¶è¡æ°æ®å¤çï¼
@Concurrent
function processChunk(chunk: collections.Array<number>): number {
return chunk.reduce((sum, val) => sum + val, 0);
}
const chunks = [new collections.Array([1,2,3]), new collections.Array([4,5,6])];
const group = new taskpool.TaskGroup();
chunks.forEach(chunk => {
group.addTask(new taskpool.Task(processChunk, chunk));
});
const results = await taskpool.execute(group);
const total = results.reduce((sum, val) => sum + val, 0);
Workeræ¶æ¯ä¼ éï¼
// 主线ç¨
workerInstance.postMessage({ type: 'fetch', url: '...' });
workerInstance.onmessage = (event) => {
if (event.data.type === 'result') {
handleResult(event.data.payload);
}
};
æ§è½èè
- TaskPoolå¼éï¼ æ¯ä¸ªä»»å¡çº¦1-2msï¼æ¹éå¤çå°æä½
- æ°æ®ä¼ è¾ï¼ 16MBéå¶ï¼å¤§ç¼å²åºä½¿ç¨Transferable
- çº¿ç¨æ°éï¼ æå¤§ä¸ºCPUæ ¸æ°ï¼èªå¨æ©ç¼©å®¹
- ä¼å çº§ï¼ åå°åæ¥/å¤ä»½ä»»å¡ä½¿ç¨IDLE
- Sendableï¼ å¤æå¯¹è±¡ä¼å 使ç¨Sendableèéåºåå
常è§é®é¢
| é®é¢ | åå | è§£å³æ¹æ¡ |
|---|---|---|
| 任塿ªæ§è¡ | 缺å°@Concurrentè£
é¥°å¨ |
æ·»å è£ é¥°å¨ |
| æ°æ®æå | åæ°ä¸å¯åºåå | ä» ä½¿ç¨æ¯æç±»å |
| ä»»å¡è¶ æ¶ | > 3åéCPUæ¶é´ | æå为æ´å°ä»»å¡ |
| UIå»ç» | é»å¡ä¸»çº¿ç¨ | 使ç¨TaskPoolå¤çç¹éå·¥ä½ |
| å åæ³æ¼ | Workeræªç»æ¢ | è°ç¨terminate() |
| æ°æ®æªæ´æ° | å ±äº«å¯¹è±¡éSendable | æ 记为@Sendable |
| ç«ææ¡ä»¶ | 缺å°å¼æ¥é | 使ç¨AsyncLock |
| Promiseæªæè· | 缺å°catchå¤ç | 使ç¨errorManagerçå¬unhandled rejection |
ð é误ç 鿥:
refs/error-codes.mdâ 10200001-10200301 é误ç å«ä¹åä¿®å¤å»ºè®®
è¿ä¸æ¥åè
ð æ¬å° API åè (refs/ æä»¶å¤¹):
| æä»¶ | å 容 |
|---|---|
refs/taskpool.md |
TaskPool 宿´ API â TaskãTaskGroupãä¼å 级ãå»¶æ¶æ§è¡ |
refs/worker.md |
Worker 宿´ API â ThreadWorkerãæ¶æ¯éä¿¡ãçå½å¨æ |
refs/collections.md |
å ±äº«å®¹å¨ API â collections.Array/Map/Set (跨线ç¨ä¼ é) |
refs/utils.md |
ArkTSUtils API â AsyncLockãASONãSendableå·¥å · |
refs/buffer.md |
Buffer API â äºè¿å¶æ°æ®å¤çãç¼ç è½¬æ¢ |
refs/xml.md |
XML API â XmlSerializerãXmlPullParser |
refs/containers.md |
线æ§/é线æ§å®¹å¨ API â ArrayListãHashMap çæ®éå®¹å¨ |
refs/error-codes.md |
é误ç éæ¥è¡¨ â 10200001-10200301 é误å¤ç |
宿¹ææ¡£ï¼
- TaskPool API: https://docs.openharmony.cn/application-dev/reference/apis-arkui/js-apis-taskpool/
- Worker API: https://docs.openharmony.cn/application-dev/reference/apis-arkui/js-apis-worker/
- å®¹å¨ API: https://docs.openharmony.cn/application-dev/reference/apis-arkts/js-apis-util/
- XML API: https://docs.openharmony.cn/application-dev/reference/apis-arkts/js-apis-xml/
- JSON API: https://docs.openharmony.cn/application-dev/reference/apis-arkts/js-apis-json/
è¯¦ç»æåï¼
- 弿¥å¹¶åæ¦è¿°:
async-concurrency-overview.md - TaskPoolç®ä»:
taskpool-introduction.md - Workerç®ä»:
worker-introduction.md - Sendable对象:
arkts-sendable.md - å
±äº«å®¹å¨:
arkts-collections-introduction.md - 弿¥é:
arkts-async-lock-introduction.md - 卿坼å
¥:
arkts-dynamic-import.md - æå¯¼å
¥:
arkts-lazy-import.md - XMLçæ:
xml-generation.md - JSONæ©å±:
arkts-json.md