Pre Merge pull request !440 from zgf/master

This commit is contained in:
zgf 2024-12-04 06:29:28 +00:00 committed by Gitee
commit 473c50a36a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 103 additions and 62 deletions

View File

@ -2,6 +2,8 @@
- Enhance: ImageFit.Auto support adaptive height after component width change - Enhance: ImageFit.Auto support adaptive height after component width change
- Fix bug: call onLoadStart 2 times(import from 3.2.0-rc.0) - Fix bug: call onLoadStart 2 times(import from 3.2.0-rc.0)
- Change the initial value of the PixelMap component of ImageKnife to ImageContent EMPTY - Change the initial value of the PixelMap component of ImageKnife to ImageContent EMPTY
- Clear memory cache, cancel pixel map release
- Loading process log modification
## 3.2.0-rc.4 ## 3.2.0-rc.4
- Support ICO format images - Support ICO format images

View File

@ -48,7 +48,7 @@ export class ImageKnifeDispatcher {
private engineKey: IEngineKey = new DefaultEngineKey(); private engineKey: IEngineKey = new DefaultEngineKey();
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean { showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean {
LogUtil.log('ImageKnife_DataTime_showFromMemomry.start:' + request.imageKnifeOption.loadSrc + 'requestSource=' + requestSource + ' isAnimator=' + isAnimator) LogUtil.log('showFromMemomry.start:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion + ' isAnimator=' + isAnimator)
let memoryCache: ImageKnifeData | undefined; let memoryCache: ImageKnifeData | undefined;
let memoryCheckStartTime = Date.now(); let memoryCheckStartTime = Date.now();
if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') { if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') {
@ -81,29 +81,29 @@ export class ImageKnifeDispatcher {
// 回调请求开始 // 回调请求开始
if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
request.imageKnifeOption.onLoadListener.onLoadStart(request) request.imageKnifeOption.onLoadListener.onLoadStart(request)
LogUtil.log('ImageKnife_DataTime_MemoryCache_onLoadStart:' + request.imageKnifeOption.loadSrc) LogUtil.log('MemoryCache_onLoadStart:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
} }
LogUtil.log('ImageKnife_DataTime_MemoryCache_showPixelMap.start:' + request.imageKnifeOption.loadSrc) this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData);
LogUtil.log('MemoryCache_showPixelMap.start:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source,
{ width: memoryCache.imageWidth, height: memoryCache.imageHeight }, requestSource, memoryCache.imageAnimator) { width: memoryCache.imageWidth, height: memoryCache.imageHeight }, requestSource, memoryCache.imageAnimator)
LogUtil.log('ImageKnife_DataTime_MemoryCache_showPixelMap.end:' + request.imageKnifeOption.loadSrc) LogUtil.log('MemoryCache_showPixelMap.end:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
if (requestSource == ImageKnifeRequestSource.SRC) { if (requestSource == ImageKnifeRequestSource.SRC) {
request.requestState = ImageKnifeRequestState.COMPLETE request.requestState = ImageKnifeRequestState.COMPLETE
// 回调请求开结束 // 回调请求开结束
if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) { if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) {
this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData);
request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache, request) request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache, request)
LogUtil.log('ImageKnife_DataTime_MemoryCache_onLoadSuccess:' + request.imageKnifeOption.loadSrc) LogUtil.log('MemoryCache_onLoadSuccess:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
} }
} else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) { } else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) {
request.requestState = ImageKnifeRequestState.ERROR request.requestState = ImageKnifeRequestState.ERROR
} }
} }
LogUtil.log('ImageKnife_DataTime_showFromMemomry.end_hasmemory:' + request.imageKnifeOption.loadSrc) LogUtil.log('showFromMemomry.end_hasmemory:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
return true return true
} }
LogUtil.log('ImageKnife_DataTime_showFromMemomry.end_nomemory:' + request.imageKnifeOption.loadSrc) LogUtil.log('showFromMemomry.end_nomemory:' + request.componentId + ',srcType:' + requestSource + ',version:' + request.componentVersion)
return false return false
} }
@ -175,7 +175,7 @@ export class ImageKnifeDispatcher {
} }
executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void { executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void {
LogUtil.log('ImageKnife_DataTime_executeJob.start:' + request.imageKnifeOption.loadSrc) LogUtil.log('executeJob.start:' + request.componentId + ',version:' + request.componentVersion)
// 加载占位符 // 加载占位符
if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) { if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) {
this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
@ -183,17 +183,17 @@ export class ImageKnifeDispatcher {
// 加载主图 // 加载主图
this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator) this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)
LogUtil.log('ImageKnife_DataTime_executeJob.end:' + request.imageKnifeOption.loadSrc) LogUtil.log('executeJob.end:' + request.componentId + ',version:' + request.componentVersion)
} }
/** /**
* 获取和显示图片 * 获取和显示图片
*/ */
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void { getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void {
LogUtil.log('ImageKnife_DataTime_getAndShowImage.start:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
if (requestSource === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { if (requestSource === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) {
currentRequest.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest) currentRequest.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest)
LogUtil.log('ImageKnife_DataTime_getAndShowImage_onLoadStart:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_onLoadStart:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight) let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight)
@ -206,7 +206,7 @@ export class ImageKnifeDispatcher {
requestList.add({ request: currentRequest, source: requestSource }) requestList.add({ request: currentRequest, source: requestSource })
return return
} }
LogUtil.info('image load getAndShowImage start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
let isWatchProgress : boolean = false let isWatchProgress : boolean = false
if (currentRequest.imageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) { if (currentRequest.imageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) {
isWatchProgress = true isWatchProgress = true
@ -249,7 +249,9 @@ export class ImageKnifeDispatcher {
targetWidth: currentRequest.componentWidth, targetWidth: currentRequest.componentWidth,
targetHeight: currentRequest.componentHeight, targetHeight: currentRequest.componentHeight,
downsampType: currentRequest.imageKnifeOption.downsampleOf == undefined ? DownsampleStrategy.DEFAULT : currentRequest.imageKnifeOption.downsampleOf, downsampType: currentRequest.imageKnifeOption.downsampleOf == undefined ? DownsampleStrategy.DEFAULT : currentRequest.imageKnifeOption.downsampleOf,
isAutoImageFit: currentRequest.imageKnifeOption.objectFit == ImageFit.Auto isAutoImageFit: currentRequest.imageKnifeOption.objectFit == ImageFit.Auto,
componentId: currentRequest.componentId,
componentVersion: currentRequest.componentVersion
} }
if(request.customGetImage == undefined) { if(request.customGetImage == undefined) {
@ -262,26 +264,26 @@ export class ImageKnifeDispatcher {
if (isWatchProgress){ if (isWatchProgress){
emitter.off(Constants.PROGRESS_EMITTER + memoryKey) emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
} }
LogUtil.log('ImageKnife_DataTime_getAndShowImage_execute.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_execute.end:'+ currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
LogUtil.log('ImageKnife_DataTime_getAndShowImage.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage.end:'+ currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
}) })
if (ImageKnife.getInstance().isRequestInSubThread){ if (ImageKnife.getInstance().isRequestInSubThread){
// 启动线程下载和解码主图 // 启动线程下载和解码主图
LogUtil.log('ImageKnife_DataTime_getAndShowImage_Task.start:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('etAndShowImage_Task.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
let task = new taskpool.Task(requestJob, request) let task = new taskpool.Task(requestJob, request)
LogUtil.log('ImageKnife_DataTime_getAndShowImage_Task.end:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_Task.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
if (isWatchProgress){ if (isWatchProgress){
emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => { emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => {
this.progressCallBack(requestList! , data?.data?.value as number) this.progressCallBack(requestList! , data?.data?.value as number)
}); });
} }
LogUtil.log('ImageKnife_DataTime_getAndShowImage_execute.start(subthread):' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_execute.start(subthread):' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
taskpool.execute(task).then((res: Object) => { taskpool.execute(task).then((res: Object) => {
}).catch((err: BusinessError) => { }).catch((err: BusinessError) => {
emitter.off(Constants.CALLBACK_EMITTER + memoryKey) emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
LogUtil.error('Fail to requestJob in sub thread src=' + imageSrc + ' err=' + err) LogUtil.error('Fail to requestJob in sub thread src=' + imageSrc + ' err=' + err)
LogUtil.log('ImageKnife_DataTime_getAndShowImage.end:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
if (isWatchProgress){ if (isWatchProgress){
emitter.off(Constants.PROGRESS_EMITTER + memoryKey) emitter.off(Constants.PROGRESS_EMITTER + memoryKey)
} }
@ -304,12 +306,12 @@ export class ImageKnifeDispatcher {
}, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator) }, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator)
}) })
} else { //主线程请求 } else { //主线程请求
LogUtil.log('ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_execute.start(mainthread):' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
requestJob(request, requestList).then(() => { requestJob(request, requestList).then(() => {
}).catch((err: BusinessError) => { }).catch((err: BusinessError) => {
emitter.off(Constants.CALLBACK_EMITTER + memoryKey) emitter.off(Constants.CALLBACK_EMITTER + memoryKey)
LogUtil.error('Fail to requestJob in main thread src=' + imageSrc + ' err=' + err) LogUtil.error('Fail to requestJob in main thread src=' + imageSrc + ' err=' + err)
LogUtil.log('ImageKnife_DataTime_getAndShowImage.end:' + currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
this.doTaskCallback({ this.doTaskCallback({
pixelMap: undefined, pixelMap: undefined,
@ -347,7 +349,7 @@ export class ImageKnifeDispatcher {
private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List<ImageKnifeRequestWithSource> , private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List<ImageKnifeRequestWithSource> ,
currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean):void { currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean):void {
LogUtil.log('ImageKnife_DataTime_getAndShowImage_CallBack.start:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_CallBack.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
if (requestJobResult === undefined){ if (requestJobResult === undefined){
return return
} }
@ -359,7 +361,7 @@ export class ImageKnifeDispatcher {
let pixelmap = requestJobResult.pixelMap; let pixelmap = requestJobResult.pixelMap;
if (pixelmap === undefined) { if (pixelmap === undefined) {
LogUtil.error('ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap failed:'+currentRequest.imageKnifeOption.loadSrc + " error: " + requestJobResult.loadFail) LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail)
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR requestWithSource.request.requestState = ImageKnifeRequestState.ERROR
this.executingJobMap.remove(memoryKey); this.executingJobMap.remove(memoryKey);
@ -369,7 +371,7 @@ export class ImageKnifeDispatcher {
requestJobResult.loadFail) { requestJobResult.loadFail) {
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData, requestWithSource.request) this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData, requestWithSource.request)
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request); requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request);
LogUtil.log('ImageKnife_DataTime_getAndShowImage_onLoadFailed:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_onLoadFailed:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
if (requestWithSource.source === ImageKnifeRequestSource.SRC && if (requestWithSource.source === ImageKnifeRequestSource.SRC &&
requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) { requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) {
@ -386,9 +388,9 @@ export class ImageKnifeDispatcher {
} }
// 保存文件缓存 // 保存文件缓存
if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) { if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) {
LogUtil.log('ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_saveWithoutWriteFile.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
ImageKnife.getInstance().saveWithoutWriteFile(requestJobResult.fileKey, requestJobResult.bufferSize); ImageKnife.getInstance().saveWithoutWriteFile(requestJobResult.fileKey, requestJobResult.bufferSize);
LogUtil.log('ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_saveWithoutWriteFile.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
let imageKnifeData: ImageKnifeData; let imageKnifeData: ImageKnifeData;
@ -426,11 +428,11 @@ export class ImageKnifeDispatcher {
// 保存内存缓存 // 保存内存缓存
if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) { if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) {
LogUtil.log('ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_saveMemoryCache.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
ImageKnife.getInstance() ImageKnife.getInstance()
.saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight), .saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight),
saveCacheImageData); saveCacheImageData);
LogUtil.log('ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_saveMemoryCache.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
if (requestList !== undefined) { if (requestList !== undefined) {
// key相同的request一起绘制 // key相同的request一起绘制
@ -441,11 +443,12 @@ export class ImageKnifeDispatcher {
requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER
|| (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && || (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER &&
requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) { requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) {
LogUtil.log('ImageKnife_DataTime_getAndShowImage_showPixelMap.start:'+currentRequest.imageKnifeOption.loadSrc) this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,requestWithSource.request);
LogUtil.log('getAndShowImage_showPixelMap.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion, requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion,
imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight }, imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight },
requestWithSource.source, imageKnifeData.imageAnimator); requestWithSource.source, imageKnifeData.imageAnimator);
LogUtil.log('ImageKnife_DataTime_getAndShowImage_showPixelMap.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_showPixelMap.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
if (requestWithSource.source == ImageKnifeRequestSource.SRC) { if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
@ -453,10 +456,9 @@ export class ImageKnifeDispatcher {
if (requestWithSource.request.imageKnifeOption.onLoadListener && if (requestWithSource.request.imageKnifeOption.onLoadListener &&
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) { requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) {
// 回调请求成功 // 回调请求成功
this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,requestWithSource.request);
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source, requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source,
saveCacheImageData, requestWithSource.request); saveCacheImageData, requestWithSource.request);
LogUtil.log('ImageKnife_DataTime_getAndShowImage_onLoadSuccess:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_onLoadSuccess:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
} else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) {
requestWithSource.request.requestState = ImageKnifeRequestState.ERROR; requestWithSource.request.requestState = ImageKnifeRequestState.ERROR;
@ -476,6 +478,7 @@ export class ImageKnifeDispatcher {
} }
} }
this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request) this.assembleImageKnifeData(callBackData,requestJobResult.imageKnifeData,requestWithSource.request)
LogUtil.log('getAndShowImage cancel:' + requestWithSource.request.componentId + ',srcType:' + requestSource + ',version:' + requestWithSource.request.componentVersion)
requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed', requestWithSource.request) requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed', requestWithSource.request)
} }
} }
@ -486,12 +489,12 @@ export class ImageKnifeDispatcher {
} else { } else {
LogUtil.log('error: no requestlist need to draw for key = ' + memoryKey); LogUtil.log('error: no requestlist need to draw for key = ' + memoryKey);
} }
LogUtil.log('ImageKnife_DataTime_getAndShowImage_CallBack.end:'+currentRequest.imageKnifeOption.loadSrc) LogUtil.log('getAndShowImage_CallBack.end:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion)
} }
dispatchNextJob() { dispatchNextJob() {
LogUtil.log('ImageKnife_DataTime_dispatchNextJob.start') LogUtil.log('dispatchNextJob.start')
// 主图和错误图并发加载时以及主图加载失败后立即加载错误图可能会导致短时间内并发数超过maxRequests故此处减少响应的并发 // 主图和错误图并发加载时以及主图加载失败后立即加载错误图可能会导致短时间内并发数超过maxRequests故此处减少响应的并发
if (this.executingJobMap.length >= this.maxRequests) { if (this.executingJobMap.length >= this.maxRequests) {
@ -501,13 +504,13 @@ export class ImageKnifeDispatcher {
while (true) { while (true) {
let request = this.jobQueue.pop() let request = this.jobQueue.pop()
if (request === undefined) { if (request === undefined) {
LogUtil.log('ImageKnife_DataTime_dispatchNextJob.end:no any job') LogUtil.log('dispatchNextJob.end:no any job')
break // 队列已无任务 break // 队列已无任务
} }
else if (request.requestState === ImageKnifeRequestState.PROGRESS) { else if (request.requestState === ImageKnifeRequestState.PROGRESS) {
LogUtil.log('ImageKnife_DataTime_dispatchNextJob.start executeJob:' + request.imageKnifeOption.loadSrc) LogUtil.log('dispatchNextJob.start executeJob:' + request.componentId + ',version:' + request.componentVersion)
this.executeJob(request) this.executeJob(request)
LogUtil.log('ImageKnife_DataTime_dispatchNextJob.end executeJob:' + request.imageKnifeOption.loadSrc) LogUtil.log('dispatchNextJob.end executeJob:' + request.componentId + ',version:' + request.componentVersion)
break break
}else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) { }else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) {
//构建回调错误信息 //构建回调错误信息
@ -522,6 +525,7 @@ export class ImageKnifeDispatcher {
}; };
callBackData.errorInfo = errorInfo; callBackData.errorInfo = errorInfo;
} }
LogUtil.log('dispatchNextJob cancel:' + request.componentId + ',version:' + request.componentVersion)
request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed', request) request.imageKnifeOption.onLoadListener.onLoadCancel('component has destroyed', request)
} }
} }
@ -550,7 +554,7 @@ export class ImageKnifeDispatcher {
*/ */
@Concurrent @Concurrent
async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>) { async function requestJob(request: RequestJobRequest, requestList?: List<ImageKnifeRequestWithSource>) {
LogUtil.log('ImageKnife_DataTime_requestJob.start:' + request.src + ' requestSource=' + request.requestSource) LogUtil.log('requestJob.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
let src = typeof request.src == 'number' ? request.resName != undefined ? request.resName : request.src + '' : request.src let src = typeof request.src == 'number' ? request.resName != undefined ? request.resName : request.src + '' : request.src
// 生成文件缓存key // 生成文件缓存key
let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator) let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator)

View File

@ -35,6 +35,7 @@ import util from '@ohos.util';
import { FileTypeUtil } from './utils/FileTypeUtil'; import { FileTypeUtil } from './utils/FileTypeUtil';
import { DownsampleStrategy } from './downsampling/DownsampleStartegy'; import { DownsampleStrategy } from './downsampling/DownsampleStartegy';
import { Downsampler } from './downsampling/Downsampler'; import { Downsampler } from './downsampling/Downsampler';
import { common } from '@kit.AbilityKit';
class RequestData { class RequestData {
receiveSize: number = 2000 receiveSize: number = 2000
@ -53,8 +54,14 @@ export class ImageKnifeLoader {
callBackData.bufSize = resBuf.byteLength; callBackData.bufSize = resBuf.byteLength;
let typeValue = new FileTypeUtil().getFileType(resBuf); let typeValue = new FileTypeUtil().getFileType(resBuf);
if(typeValue == null) { if(typeValue == null) {
LogUtil.log('ImageKnife_DataTime_requestJob.end: getFileType is null ' + request.src) let unit8 = new Uint8Array(resBuf)
ImageKnifeLoader.makeEmptyResult(request,'request is not a valid image source', ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_GET_FORMAT, LoadPixelMapCode.IMAGE_PARSE_FORMAT_FAILED_CODE)) LogUtil.log('requestJob.end: getFileType is null: ' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
ImageKnifeLoader.makeEmptyResult(request,
'request is not a valid image source:' + request.componentId + ',srcType:' + request.requestSource + ',' +
request.componentVersion + ',buffer:' + resBuf.byteLength + ',unit8:' + unit8[0] + ',' +
unit8[1] + ',' + unit8[2],
ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_GET_FORMAT,
LoadPixelMapCode.IMAGE_PARSE_FORMAT_FAILED_CODE))
return return
} }
callBackData.type = typeValue; callBackData.type = typeValue;
@ -163,9 +170,9 @@ export class ImageKnifeLoader {
return return
}) })
if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && resPixelmap !== undefined) { if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && resPixelmap !== undefined) {
LogUtil.log('ImageKnife_DataTime_requestJob.transform.start:' + request.src) LogUtil.log('requestJob.transform.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
resPixelmap = await request.transformation?.transform(request.context, resPixelmap, request.componentWidth, request.componentHeight); resPixelmap = await request.transformation?.transform(request.context, resPixelmap, request.componentWidth, request.componentHeight);
LogUtil.log('ImageKnife_DataTime_requestJob.transform.end:' + request.src) LogUtil.log('requestJob.transform.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
} }
try { try {
resPixelmap?.setTransferDetached(true) resPixelmap?.setTransferDetached(true)
@ -402,9 +409,9 @@ export class ImageKnifeLoader {
static FileCacheParseImage(request:RequestJobRequest,resBuf:ArrayBuffer,fileKey:string, callBackData: ImageKnifeData){ static FileCacheParseImage(request:RequestJobRequest,resBuf:ArrayBuffer,fileKey:string, callBackData: ImageKnifeData){
// 保存文件缓存 // 保存文件缓存
if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) { if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) {
LogUtil.log('ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:'+request.src) LogUtil.log('requestJob_saveFileCacheOnlyFile.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder) FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder)
LogUtil.log('ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:'+request.src) LogUtil.log('requestJob_saveFileCacheOnlyFile.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
} }
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData) ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
} }
@ -433,7 +440,7 @@ export class ImageKnifeLoader {
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder) resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
callBackTimeInfo.diskCheckEndTime = Date.now(); callBackTimeInfo.diskCheckEndTime = Date.now();
if (resBuf === undefined) { if (resBuf === undefined) {
LogUtil.log('start customGetImage src=' + request.src) LogUtil.log('start customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request) const headerObj: Record<string, Object> = ImageKnifeLoader.getHeaderObj(request)
try { try {
request.customGetImage(request.context, request.src, headerObj) request.customGetImage(request.context, request.src, headerObj)
@ -451,7 +458,7 @@ export class ImageKnifeLoader {
loadError = 'customGetImage loadFail failed' loadError = 'customGetImage loadFail failed'
ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE)) ImageKnifeLoader.makeEmptyResult(request,loadError + e, ImageKnifeLoader.assembleError(callBackData, LoadPhase.PHASE_CUSTOM_LOAD, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE))
} }
LogUtil.log('end customGetImage src=' + request.src) LogUtil.log('end customGetImage src=' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
return return
} }
} }
@ -464,10 +471,10 @@ export class ImageKnifeLoader {
resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder) resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder)
callBackTimeInfo.diskCheckEndTime = Date.now() callBackTimeInfo.diskCheckEndTime = Date.now()
if (resBuf !== undefined){ if (resBuf !== undefined){
LogUtil.log('success get image from filecache for key = ' + fileKey + ' src = ' + request.src) LogUtil.log('success get image from filecache for key = ' + fileKey + ' src = ' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
} }
else if (request.onlyRetrieveFromCache != true) { else if (request.onlyRetrieveFromCache != true) {
LogUtil.log('HttpDownloadClient.start:' + request.src) LogUtil.log('HttpDownloadClient.start:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
callBackTimeInfo.netRequestStartTime = Date.now(); callBackTimeInfo.netRequestStartTime = Date.now();
let httpRequest = http.createHttp(); let httpRequest = http.createHttp();
let progress: number = 0 let progress: number = 0
@ -525,7 +532,7 @@ export class ImageKnifeLoader {
callBackTimeInfo.netRequestEndTime = Date.now(); callBackTimeInfo.netRequestEndTime = Date.now();
ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, undefined)) ImageKnifeLoader.makeEmptyResult(request,loadError, ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, undefined))
}); });
LogUtil.log('HttpDownloadClient.end:' + request.src) LogUtil.log('HttpDownloadClient.end:' + request.componentId + ',srcType:' + request.requestSource + ',' + request.componentVersion)
return return
} }
else { else {
@ -552,7 +559,7 @@ export class ImageKnifeLoader {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_SHARE_FILE, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE) 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 loadError = 'LoadDataShareFileClient fs.open err happened uri=' + request.src + ' err.msg=' + err?.message + ' err.code=' + err?.code
}) })
} else { //从本地文件获取 } else if (ImageKnifeLoader.isLocalLoadSrc(request.context, request.src)) { //从本地文件获取
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE) ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE)
try { try {
let stat = fs.statSync(request.src); let stat = fs.statSync(request.src);
@ -564,8 +571,10 @@ export class ImageKnifeLoader {
} }
} catch (err) { } catch (err) {
ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE) ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_LOCAL_FILE, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE)
loadError = err loadError = 'LocalLoadSrc:' + request.src + ',err:' + err
} }
} else {
loadError = 'Parameter not supported:' + request.src
} }
} else if (typeof request.src == 'number') { //从资源文件获取 } else if (typeof request.src == 'number') { //从资源文件获取
let manager = request.context.createModuleContext(request.moduleName).resourceManager let manager = request.context.createModuleContext(request.moduleName).resourceManager
@ -594,7 +603,16 @@ export class ImageKnifeLoader {
} }
ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData) ImageKnifeLoader.parseImage(resBuf,fileKey,request, callBackData)
} }
static isLocalLoadSrc(context: Object | undefined, loadSrc: string): boolean {
if (context != undefined) {
let fileDir: string = (context as common.UIAbilityContext).filesDir as string;
let cacheDir: string = (context as common.UIAbilityContext).cacheDir as string
if (loadSrc.startsWith(fileDir) || loadSrc.startsWith(cacheDir)) {
return true;
}
}
return false;
}
static getDownsamplerDecodingOptions(typeValue: string, request: RequestJobRequest, size: Size, static getDownsamplerDecodingOptions(typeValue: string, request: RequestJobRequest, size: Size,
SRC?: ImageKnifeRequestSource):image.DecodingOptions { SRC?: ImageKnifeRequestSource):image.DecodingOptions {
let reqSize = let reqSize =

View File

@ -60,6 +60,7 @@ export class FileCache {
if (this.isInited) { if (this.isInited) {
return return
} }
let startTime = Date.now()
if (this.context && path.startsWith(this.context.cacheDir) === true) { if (this.context && path.startsWith(this.context.cacheDir) === true) {
this.path = path this.path = path
} else { } else {
@ -104,6 +105,7 @@ export class FileCache {
} }
this.trimToSize(); this.trimToSize();
LogUtil.info('image init initFileCache:' + (Date.now() - startTime) + ',num:' + filenames.length + ',nums:' + this.lruCache.length + ',size:' + this.currentMemory)
this.isInited = true this.isInited = true
} }

View File

@ -115,7 +115,7 @@ export class MemoryLruCache implements IMemoryCache {
} }
} else { } else {
this.currentMemory -= value.source.getPixelBytesNumber(); this.currentMemory -= value.source.getPixelBytesNumber();
value.source.release() // value.source.release()
} }
// LogUtil.info('MemoryCache removeMemorySize: ' + value.source.getPixelBytesNumber() + ' currentMemory' + this.currentMemory) // LogUtil.info('MemoryCache removeMemorySize: ' + value.source.getPixelBytesNumber() + ' currentMemory' + this.currentMemory)
} }

View File

@ -110,7 +110,8 @@ export struct ImageKnifeComponent {
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) { if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) {
this.isImageFitAutoResize = false this.isImageFitAutoResize = false
} else { } else {
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight)) ImageKnife.getInstance().execute(this.getRequest(
this.currentWidth, this.currentHeight, this.getUniqueId()))
} }
} }
} }
@ -127,7 +128,8 @@ export struct ImageKnifeComponent {
' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc + ' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc +
' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc + ' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc +
' componentId = ' + this.getUniqueId()) ' componentId = ' + this.getUniqueId())
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight)) ImageKnife.getInstance().execute(this.getRequest(
this.currentWidth, this.currentHeight, this.getUniqueId()))
} }
getCurrentContext(): common.UIAbilityContext { getCurrentContext(): common.UIAbilityContext {
@ -137,7 +139,7 @@ export struct ImageKnifeComponent {
return this.currentContext return this.currentContext
} }
getRequest(width: number, height: number): ImageKnifeRequest { getRequest(width: number, height: number,componentId: number): ImageKnifeRequest {
this.request = new ImageKnifeRequest( this.request = new ImageKnifeRequest(
this.imageKnifeOption, this.imageKnifeOption,
this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(), this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(),
@ -150,8 +152,15 @@ export struct ImageKnifeComponent {
return //针对reuse场景不显示历史图片 return //针对reuse场景不显示历史图片
} }
this.pixelMap = pixelMap this.pixelMap = pixelMap
LogUtil.debug('image load showPixelMap:' + this.request?.imageKnifeOption.loadSrc + ', componentId = ' + let memory = this.request?.imageKnifeData?.timeInfo?.memoryCheckEndTime ? 1 : 0
this.getUniqueId() + ',size:' + JSON.stringify(size)) let fileCache = this.request?.imageKnifeData?.timeInfo?.diskCheckEndTime ? 1 : 0
let net = this.request?.imageKnifeData?.timeInfo?.netRequestEndTime ? 1 : 0
memory = memory - fileCache
fileCache = fileCache - net
let source = memory == 1 ? 'memory' : fileCache == 1 ? 'fileCache' : 'downLoad'
LogUtil.info('image load showPixelMap:' + this.request?.componentId + ',srcType:' + requestSource +
',version:' + this.request?.componentVersion +
',size:' + JSON.stringify(size) + ',source:' + source)
if (typeof this.pixelMap !== 'string') { if (typeof this.pixelMap !== 'string') {
if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize == false) { if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize == false) {
this.adaptiveHeight = this.currentWidth * size.height / size.width this.adaptiveHeight = this.currentWidth * size.height / size.width
@ -170,7 +179,9 @@ export struct ImageKnifeComponent {
this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit
} }
} }
}) },
componentId
)
return this.request return this.request
} }
} }

View File

@ -151,6 +151,8 @@ export interface RequestJobRequest {
targetWidth: number targetWidth: number
targetHeight: number targetHeight: number
downsampType: DownsampleStrategy, downsampType: DownsampleStrategy,
isAutoImageFit: boolean isAutoImageFit: boolean,
componentId?: number,
componentVersion?: number
} }

View File

@ -28,18 +28,20 @@ export class ImageKnifeRequest {
componentVersion: number = 0 componentVersion: number = 0
headers: Map<string,Object> = new Map<string,Object>() headers: Map<string,Object> = new Map<string,Object>()
imageKnifeData?: ImageKnifeData imageKnifeData?: ImageKnifeData
componentId?: number
constructor(option: ImageKnifeOption, constructor(option: ImageKnifeOption,
uIAbilityContext: common.UIAbilityContext, uIAbilityContext: common.UIAbilityContext,
width: number, width: number,
height: number, height: number,
version: number, version: number,
ImageKnifeRequestCallback: ImageKnifeRequestCallback) { ImageKnifeRequestCallback: ImageKnifeRequestCallback,componentId?: number) {
this.imageKnifeOption = option this.imageKnifeOption = option
this.context = uIAbilityContext this.context = uIAbilityContext
this.componentWidth = width this.componentWidth = width
this.componentHeight = height this.componentHeight = height
this.componentVersion = version this.componentVersion = version
this.ImageKnifeRequestCallback = ImageKnifeRequestCallback this.ImageKnifeRequestCallback = ImageKnifeRequestCallback
this.componentId = componentId
} }
// RequestOption调用header对于的方法 // RequestOption调用header对于的方法
addHeader(key: string, value: Object) { addHeader(key: string, value: Object) {