介紹
本示例介紹在Worker 子線程使用@ohos.zlib 提供的zlib.decompressfile接口對沙箱目錄中的壓縮文件進(jìn)行解壓操作,解壓成功后將解壓路徑返回主線程,獲取解壓文件列表。
效果圖預(yù)覽
使用說明
- 點(diǎn)擊解壓按鈕,解壓test.zip文件,顯示解壓結(jié)果。
實(shí)現(xiàn)思路
- 在/src/main/ets/workers目錄下創(chuàng)建Worker.ets線程文件,綁定Worker對象。源碼參考Worker.ets
const workerPort: ThreadWorkerGlobalScope = worker.workerPort;
- 在build-profile.json5中進(jìn)行配置Worker線程文件路徑,Worker線程文件才能確保被打包到應(yīng)用中。源碼參考build-profile.json5
"buildOption": {
"sourceOption": {
"workers": [
"./src/main/ets/workers/Worker.ets"
]
}
}
- 在主線程創(chuàng)建一個Worker線程,通過new worker.ThreadWorker()創(chuàng)建Worker實(shí)例,傳入Worker.ets的加載路徑。源碼參考MainPage.ets
https://gitee.com/harmonyos-cases/cases/blob/master/CommonAppDevelopment/feature/decompressfile/build-profile.json5
- 主線程使用postMessage()向worker線程發(fā)送應(yīng)用沙箱路徑和壓縮文件名稱。源碼參考MainPage.ets
workerInstance.postMessage({ pathDir: this.pathDir, rawfileZipName: rawfileZipName });
- 在Worker.ets文件中通過調(diào)用onmessage()方法接收主線程發(fā)送的應(yīng)用沙箱路徑和壓縮文件名稱。
workerPort.onmessage = (e: MessageEvents): void => {
logger.info(TAG, `Worker onmessage:${JSON.stringify(e.data)}`);
let pathDir: string = e.data.pathDir; // 沙箱目錄
let rawfileZipName: string = e.data.rawfileZipName; // 帶.zip后綴的壓縮文件名稱
}
- 使用fs.access判斷輸出目錄是否已經(jīng)存在,如果不存在使用fs.mkdirSync()創(chuàng)建空目錄用于放置解壓后的文件。空目錄創(chuàng)建成功后使用zlib.decompressFile接口解壓壓縮文件,輸出到空目錄中。源碼參考Worker.ets
fs.access(outFileDir).then((res: boolean) => {
if (!res) {
// TODO:知識點(diǎn):使用fs.mkdirSync創(chuàng)建目錄,用于存放解壓后的文件。
fs.mkdirSync(outFileDir);
logger.info(TAG, 'mkdirSync succeed');
}
// TODO:知識點(diǎn):使用zlib.decompressfile接口對沙箱目錄中的壓縮文件進(jìn)行解壓操作,解壓至指定沙箱目錄outFileDir。
// 如果待解壓的文件或文件夾在解壓后的路徑下已經(jīng)存在,則會直接覆蓋同名文件或同名文件夾中的同名文件。
zlib.decompressFile(`${pathDir}/${rawfileZipName}`, outFileDir, (errData: BusinessError) => {
if (errData !== null) {
logger.error(TAG, `decompressFile failed. code is ${errData.code}, message is ${errData.message}`);
} else {
logger.info(TAG, `decompressFile succeed. outFileDir is ${outFileDir}`);
// TODO:知識點(diǎn):Worker線程向主線程發(fā)送信息。
workerPort.postMessage(outFileDir);
}
})
}).catch((err: BusinessError) => {
logger.error(TAG, `access failed with error message: ${err.message}, error code: ${err.code}`);
});
高性能知識點(diǎn)
- 本示例使用了LazyForEach進(jìn)行數(shù)據(jù)懶加載,List布局時會根據(jù)可視區(qū)域按需創(chuàng)建ListItem組件,并在ListItem滑出可視區(qū)域外時銷毀以降低內(nèi)存占用。參考文章正確使用LazyForEach優(yōu)化
- 本示例使用在Work子線程中使用zlib.decompressFile解壓文件,避免阻塞主線程的運(yùn)行。參考文章多線程能力場景化示例實(shí)踐。
工程結(jié)構(gòu)&模塊類型
decompressFile // har類型
|---/src/main/ets/model
| |---FileListDataSource.ets // 數(shù)據(jù)模型層-列表數(shù)據(jù)模型
| |---FileItemModel.ets // 數(shù)據(jù)模型層-列表項(xiàng)數(shù)據(jù)模型
|---/src/main/ets/view
| |---MainPage.ets // 視圖層-場景列表頁面
|---/src/main/ets/workers
| |---Worker.ets // Worker線程
模塊依賴
- 本實(shí)例依賴common模塊來獲取日志工具類logger。