!458 优化ImageKnifeLoader类的getImageArrayBuffer方法

Merge pull request !458 from 刘海康/master
This commit is contained in:
openharmony_ci 2025-02-07 09:12:11 +00:00 committed by Gitee
commit 933cc284ec
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 480 additions and 173 deletions

View File

@ -214,9 +214,7 @@ export class ImageKnifeDispatcher {
if((imageSrc as Resource).id != undefined) {
moduleName = (imageSrc as Resource).moduleName
src = (imageSrc as Resource).id
if(src == -1) {
resName = (imageSrc as Resource).params![0]
}
} else if(typeof imageSrc == 'string') {
src = imageSrc
}

View File

@ -36,6 +36,7 @@ import { FileTypeUtil } from './utils/FileTypeUtil';
import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
import { Downsampler } from './downsampling/Downsampler';
import { common } from '@kit.AbilityKit';
import { ImageLoaderFactory } from './loaderStrategy/ImageLoaderFactory';
class RequestData {
receiveSize: number = 2000
@ -445,178 +446,14 @@ export class ImageKnifeLoader {
errorInfo: error
};
// 判断自定义下载
if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == 'string') {
// 先从文件缓存获取
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_CUSTOM_LOAD)
callBackTimeInfo.diskCheckStartTime = Date.now();
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
callBackTimeInfo.diskCheckEndTime = Date.now();
if (resBuf === undefined) {
LogUtil.log('start customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
try {
request.customGetImage(request.context, request.src, headerObj)
.then((buffer)=>{
if(buffer != undefined) {
ImageKnifeLoader.FileCacheParseImage(request,buffer,fileKey,callBackData)
const loaderStrategy = ImageLoaderFactory.getLoaderStrategy(request);
if (loaderStrategy) {
await loaderStrategy.loadImage(request, requestList, fileKey, callBackData, callBackTimeInfo);
} else {
loadError = 'customGetImage loadFail undefined'
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
}
}).catch((err:string)=>{
ImageKnifeLoader.makeEmptyResult(request,err, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
})
} catch (e) {
loadError = 'customGetImage loadFail failed'
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
}
LogUtil.log('end customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
return
}
}
else {
if (typeof request.src === 'string') {
if (request.src.indexOf('http://') == 0 || request.src.indexOf('https://') == 0) { //从网络下载
// 先从文件缓存获取
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET)
LogUtil.log('get fileCache buffer start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
callBackTimeInfo.diskCheckStartTime = Date.now()
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
callBackTimeInfo.diskCheckEndTime = Date.now()
LogUtil.log('get fileCache buffer end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
if (resBuf !== undefined){
LogUtil.log('success get image from filecache for key = ' + fileKey + ' src = ' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
}
else if (request.onlyRetrieveFromCache != true) {
LogUtil.log('HttpDownloadClient.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
callBackTimeInfo.netRequestStartTime = Date.now();
let httpRequest = http.createHttp();
let progress: number = 0
let arrayBuffers:ArrayBuffer[] = []
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
arrayBuffers.push(data)
});
if (request.isWatchProgress) {
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
// 下载进度
if (data != undefined && (typeof data.receiveSize == 'number') && (typeof data.totalSize == 'number')) {
let percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100)
if (progress !== percent) {
progress = percent
if (requestList === undefined) {
// 子线程
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { 'value': progress } })
}else {
// 主线程请求
requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) {
requestWithSource.request.imageKnifeOption.progressListener(progress)
}
})
}
}
}
})
}
let promise = httpRequest.requestInStream(request.src, {
header: headerObj,
method: http.RequestMethod.GET,
expectDataType: http.HttpDataType.ARRAY_BUFFER,
connectTimeout: request.connectTimeout == undefined ? 60000 : request.connectTimeout,
readTimeout: request.readTimeout == undefined ? 30000 : request.readTimeout,
caPath: request.caPath === undefined ? undefined : request.caPath,
});
promise.then((data: number) => {
LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
callBackData.httpCode = data
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined)
callBackTimeInfo.netRequestEndTime = Date.now();
if (data == 200 || data == 206 || data == 204) {
resBuf = combineArrayBuffers(arrayBuffers)
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData)
} else {
loadError = 'HttpDownloadClient has error, http code =' + JSON.stringify(data)
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE))
}
}).catch((err: BusinessError) => {
callBackData.httpCode = err.code
loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err)
callBackTimeInfo.netRequestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE))
});
return
}
else {
callBackTimeInfo.netRequestEndTime = Date.now();
loadError = 'onlyRetrieveFromCache,do not fetch image src = ' + request.src
}
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE)
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
await fs.stat(file.fd).then(async (stat) =>{
let buf = new ArrayBuffer(stat.size);
await fs.read(file.fd, buf).then((readLen) => {
resBuf = buf;
fs.closeSync(file.fd);
}).catch((err:BusinessError) => {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
})
}).catch((err:BusinessError) => {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
})
}).catch((err:BusinessError) => {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
})
} else if (ImageKnifeLoader.isLocalLoadSrc(request.context, request.src)) { //从本地文件获取
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE)
try {
let stat = fs.statSync(request.src);
if (stat.size > 0) {
let file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
resBuf = new ArrayBuffer(stat.size);
fs.readSync(file.fd, resBuf);
fs.closeSync(file);
}
} catch (err) {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE)
loadError = 'LocalLoadSrc:' + request.src + ',err:' + err
}
} else {
loadError = 'Parameter not supported:' + request.src
}
} else if (typeof request.src == 'number') { //从资源文件获取
let manager = request.context.createModuleContext(request.moduleName).resourceManager
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) {
if(request.src == -1) {
let resName = request.resName as string
resBuf = (await manager.getMediaByName(resName.substring(resName.lastIndexOf(".") + 1))).buffer as ArrayBuffer
} else {
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
}
} else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) {
if(request.src == -1) {
let resName = request.resName as string
resBuf = (await manager.getMediaByName(resName.substring(resName.lastIndexOf(".") + 1))).buffer as ArrayBuffer
} else {
resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer
}
}
}
}
if (resBuf === undefined){
loadError = `Unsupported request type: ${request.src}`;
callBackTimeInfo.requestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request,loadError ,callBackData)
return
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
}
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
}
static isLocalLoadSrc(context: Object | undefined, loadSrc: string): boolean {
if (context != undefined) {

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FileCache } from '../cache/FileCache';
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import { ImageKnifeLoader } from '../ImageKnifeLoader';
import { ImageKnifeData, ImageKnifeRequestWithSource, RequestJobRequest, TimeInfo } from '../model/ImageKnifeData';
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
import { LogUtil } from '../utils/LogUtil';
import List from '@ohos.util.List';
// 自定义加载策略
export class CustomLoaderStrategy implements IImageLoaderStrategy {
async loadImage(
request: RequestJobRequest,
requestList: List<ImageKnifeRequestWithSource> | undefined,
fileKey: string,
callBackData: ImageKnifeData,
callBackTimeInfo: TimeInfo
): Promise<void> {
let resBuf: ArrayBuffer | undefined;
let loadError: string = '';
// 从文件缓存获取
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD);
callBackTimeInfo.diskCheckStartTime = Date.now();
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder);
callBackTimeInfo.diskCheckEndTime = Date.now();
if (resBuf !== undefined) {
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
} else if (!request.onlyRetrieveFromCache) {
LogUtil.log('start customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' +
request.componentVersion);
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request);
try {
request.customGetImage!(request.context, request.src as string, headerObj)
.then((buffer)=>{
if(buffer !== undefined && buffer !== null) {
ImageKnifeLoader.FileCacheParseImage(request,buffer,fileKey,callBackData);
} else {
loadError = 'customGetImage loadFail undefined';
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
}
}).catch((err:string)=>{
ImageKnifeLoader.makeEmptyResult(request,err, ImageKnifeLoader.assembleError(callBackData,
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
})
} catch (e) {
loadError = 'customGetImage loadFail failed';
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData,
LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE));
}
LogUtil.log('end customGetImage src=' + request.componentId + ',srcType:' +
request.requestSource + ',' + request.componentVersion);
return;
} else {
loadError = `onlyRetrieveFromCache, do not fetch image src = ${request.src}`;
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
}
return;
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { RequestJobRequest, ImageKnifeRequestWithSource, ImageKnifeData, TimeInfo } from '../model/ImageKnifeData';
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import List from '@ohos.util.List';
import { ImageKnifeLoader } from '../ImageKnifeLoader';
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
import fs from '@ohos.file.fs';
export class FileLocalLoadStrategy implements IImageLoaderStrategy {
loadImage(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined, fileKey: string,
callBackData: ImageKnifeData, callBackTimeInfo: TimeInfo): Promise<void> {
let resBuf: ArrayBuffer | undefined;
let loadError: string = '';
if (typeof request.src === 'string' && ImageKnifeLoader.isLocalLoadSrc(request.context, request.src)) {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_LOCAL_FILE);
try {
const stat = fs.statSync(request.src);
if (stat.size > 0) {
const file = fs.openSync(request.src, fs.OpenMode.READ_ONLY);
resBuf = new ArrayBuffer(stat.size);
fs.readSync(file.fd, resBuf);
fs.closeSync(file);
}
} catch (err) {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_LOCAL_FILE,
LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE);
loadError = `LocalLoadSrc: ${request.src}, err: ${err}`;
ImageKnifeLoader.makeEmptyResult(request, loadError,
ImageKnifeLoader.assembleError(
callBackData,
LoadPhase.PHASE_LOCAL_FILE,
LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE
)
);
}
} else {
loadError = `Parameter not supported: ${request.src}`;
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
}
if (resBuf === undefined || resBuf === null) {
callBackTimeInfo.requestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
} else {
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
}
return Promise.resolve();
}
}

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeData, RequestJobRequest, TimeInfo, ImageKnifeRequestWithSource } from '../model/ImageKnifeData';
import fs from '@ohos.file.fs';
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import List from '@ohos.util.List';
import { ImageKnifeLoader } from '../ImageKnifeLoader';
import { LoadPhase, LoadPixelMapCode } from '../utils/Constants';
import { BusinessError } from '@kit.BasicServicesKit';
export class FileSystemLoaderStrategy implements IImageLoaderStrategy {
async loadImage(request: RequestJobRequest, requestList: List<ImageKnifeRequestWithSource> | undefined,
fileKey: string, callBackData: ImageKnifeData, callBackTimeInfo: TimeInfo
): Promise<void> {
let resBuf: ArrayBuffer | undefined;
let loadError: string = '';
if (typeof request.src === 'string' &&
(request.src.startsWith('datashare://') || request.src.startsWith('file://'))) {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE);
await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => {
await fs.stat(file.fd).then(async (stat) => {
let buf = new ArrayBuffer(stat.size);
await fs.read(file.fd, buf).then((readLen) => {
resBuf = buf;
fs.closeSync(file.fd);
}).catch((err: BusinessError) => {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.read err happened uri=' + request.src + ' err.msg=' + err?.message +
' err.code=' + err?.code
})
}).catch((err: BusinessError) => {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.stat err happened uri=' + request.src + ' err.msg=' + err?.message +
' err.code=' + err?.code
})
}).catch((err: BusinessError) => {
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_SHARE_FILE,
LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE)
loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + ' err.msg=' + err?.message +
' err.code=' + err?.code
})
}
if (resBuf === undefined || resBuf === null) {
callBackTimeInfo.requestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
} else {
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
}
return;
}
}

View File

@ -0,0 +1,133 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FileCache } from '../cache/FileCache';
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import {
ImageKnifeData,
ImageKnifeRequestSource,
ImageKnifeRequestWithSource,
RequestJobRequest,
TimeInfo
} from '../model/ImageKnifeData';
import http from '@ohos.net.http';
import { ImageKnifeLoader } from '../ImageKnifeLoader';
import { combineArrayBuffers } from '../utils/ArrayBufferUtils';
import { BusinessError, emitter } from '@kit.BasicServicesKit';
import { Constants, LoadPhase, LoadPixelMapCode } from '../utils/Constants';
import { LogUtil } from '../utils/LogUtil';
import List from '@ohos.util.List';
class RequestData {
public receiveSize: number = 2000
public totalSize: number = 2000
}
// HTTP加载策略
export class HttpLoaderStrategy implements IImageLoaderStrategy {
async loadImage(
request: RequestJobRequest,
requestList: List<ImageKnifeRequestWithSource> | undefined,
fileKey: string,
callBackData: ImageKnifeData,
callBackTimeInfo: TimeInfo
): Promise<void> {
let resBuf: ArrayBuffer | undefined;
let loadError: string = '';
// 从文件缓存获取
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_NET);
callBackTimeInfo.diskCheckStartTime = Date.now();
resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder);
callBackTimeInfo.diskCheckEndTime = Date.now();
if (resBuf !== undefined) {
LogUtil.log(`success get image from filecache for key = ${fileKey} src = ${request.componentId},
srcType:${request.requestSource}, ${request.componentVersion}`);
ImageKnifeLoader.parseImage(resBuf, fileKey, request, callBackData);
} else if (request.onlyRetrieveFromCache !== true) {
LogUtil.log(`HttpDownloadClient.start: ${request.componentId}, srcType:${request.requestSource},
${request.componentVersion}`);
callBackTimeInfo.netRequestStartTime = Date.now();
const httpRequest = http.createHttp();
let progress: number = 0;
const arrayBuffers: ArrayBuffer[] = [];
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request);
httpRequest.on('dataReceive', (data: ArrayBuffer) => {
arrayBuffers.push(data);
});
if (request.isWatchProgress) {
httpRequest.on('dataReceiveProgress', (data: RequestData) => {
if (data != undefined && typeof data.receiveSize === 'number' && typeof data.totalSize === 'number') {
const percent = Math.round(((data.receiveSize * 1.0) / (data.totalSize * 1.0)) * 100);
if (progress !== percent) {
progress = percent;
if (requestList === undefined) {
// 子线程
emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { 'value': progress } });
} else {
// 主线程请求
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
if (requestWithSource.request.imageKnifeOption.progressListener !== undefined &&
requestWithSource.source === ImageKnifeRequestSource.SRC) {
requestWithSource.request.imageKnifeOption.progressListener(progress);
}
});
}
}
}
});
}
let promise = httpRequest.requestInStream(request.src as string, {
header: headerObj,
method: http.RequestMethod.GET,
expectDataType: http.HttpDataType.ARRAY_BUFFER,
connectTimeout: request.connectTimeout === undefined || request.connectTimeout === null ?
60000 : request.connectTimeout,
readTimeout: request.readTimeout === undefined || request.readTimeout === null?
30000 : request.readTimeout,
caPath: request.caPath
});
promise.then((data: number) => {
callBackData.httpCode = data;
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined);
callBackTimeInfo.netRequestEndTime = Date.now();
if (data == 200 || data == 206 || data == 204) {
resBuf = combineArrayBuffers(arrayBuffers);
ImageKnifeLoader.FileCacheParseImage(request,resBuf,fileKey, callBackData);
} else {
loadError = 'HttpDownloadClient has error, http code =' + JSON.stringify(data);
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
}
}).catch((err: BusinessError) => {
callBackData.httpCode = err.code;
loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err);
callBackTimeInfo.netRequestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,
LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE));
});
LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' +
request.requestSource + ',' + request.componentVersion);
return;
} else {
callBackTimeInfo.netRequestEndTime = Date.now();
loadError = `onlyRetrieveFromCache, do not fetch image src = ${request.src}`;
ImageKnifeLoader.makeEmptyResult(request, loadError, callBackData);
return;
}
}
}

View File

@ -0,0 +1,27 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ImageKnifeData, ImageKnifeRequestWithSource, RequestJobRequest, TimeInfo } from '../model/ImageKnifeData';
import List from '@ohos.util.List';
// 定义图片加载策略接口
export interface IImageLoaderStrategy {
loadImage(
request: RequestJobRequest,
requestList: List<ImageKnifeRequestWithSource> | undefined,
fileKey: string,
callBackData: ImageKnifeData,
callBackTimeInfo: TimeInfo
): Promise<void>;
}

View File

@ -0,0 +1,44 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 加载策略工厂
import { CustomLoaderStrategy } from './CustomLoaderStrategy';
import { FileSystemLoaderStrategy } from './FileSystemLoaderStrategy';
import { HttpLoaderStrategy } from './HttpLoaderStrategy';
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import { ImageKnifeRequestSource, RequestJobRequest } from '../model/ImageKnifeData';
import { ResourceLoaderStrategy } from './ResourceLoaderStrategy';
import { FileLocalLoadStrategy } from './FileLocalLoadStrategy';
export class ImageLoaderFactory {
static getLoaderStrategy(request: RequestJobRequest): IImageLoaderStrategy | null {
if (request.customGetImage !== undefined &&
request.requestSource === ImageKnifeRequestSource.SRC &&
typeof request.src === 'string'
) {
return new CustomLoaderStrategy();
} else if (typeof request.src === 'string') {
if (request.src.startsWith('http://') || request.src.startsWith('https://')) {
return new HttpLoaderStrategy();
} else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) {
return new FileSystemLoaderStrategy();
} else {
return new FileLocalLoadStrategy();
}
} else if (typeof request.src === 'number') {
return new ResourceLoaderStrategy();
}
return null;
}
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the 'License');
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an 'AS IS' BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 资源文件加载策略
import { IImageLoaderStrategy } from './IImageLoaderStrategy';
import {
ImageKnifeData,
ImageKnifeRequestSource,
ImageKnifeRequestWithSource,
RequestJobRequest,
TimeInfo
} from '../model/ImageKnifeData';
import List from '@ohos.util.List';
import { application } from '@kit.AbilityKit';
import { ImageKnifeLoader } from '../ImageKnifeLoader';
export class ResourceLoaderStrategy implements IImageLoaderStrategy {
async loadImage(
request: RequestJobRequest,
requestList: List<ImageKnifeRequestWithSource> | undefined,
fileKey: string,
callBackData: ImageKnifeData,
callBackTimeInfo: TimeInfo
): Promise<void> {
let resBuf: ArrayBuffer | undefined;
let loadError: string = '';
if (typeof request.src === 'number') {
const moduleContext = await application.createModuleContext(request.context, request.moduleName);
const manager = moduleContext.resourceManager;
if ((resBuf == undefined && request.onlyRetrieveFromCache !== true &&
request.requestSource === ImageKnifeRequestSource.SRC) ||
(resBuf == undefined && request.requestSource !== ImageKnifeRequestSource.SRC)) {
if (request.src === -1) {
const resName = request.resName as string;
resBuf =
(await manager.getMediaByName(resName.substring(resName.lastIndexOf('.') + 1))).buffer as ArrayBuffer;
} else {
resBuf = request.resName ?
manager.getRawFileContentSync(request.resName).buffer.slice(0) :
(manager.getMediaContentSync(request.src)).buffer as ArrayBuffer;
}
}
}
if (resBuf === undefined || resBuf === null){
callBackTimeInfo.requestEndTime = Date.now();
loadError = 'Resource load error';
ImageKnifeLoader.makeEmptyResult(request, loadError ,callBackData);
} else {
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData);
}
return;
}
}