From 06c16d49dff4625f082da10a2e2fd8da80e2b42d Mon Sep 17 00:00:00 2001 From: zgf Date: Mon, 10 Feb 2025 17:19:49 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0ImageKnifeComponent=E7=BB=84?= =?UTF-8?q?=E4=BB=B6=E9=94=80=E6=AF=81=E7=BD=91=E7=BB=9C=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E4=B8=AD=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: zgf --- CHANGELOG.md | 4 ++ .../main/ets/pages/MultipleImageCallBack.ets | 2 +- library/src/main/ets/ImageKnife.ets | 4 ++ library/src/main/ets/ImageKnifeDispatcher.ets | 57 +++++++++++++------ .../ets/components/ImageKnifeComponent.ets | 18 ++++-- .../ets/loaderStrategy/HttpLoaderStrategy.ets | 4 ++ 6 files changed, 67 insertions(+), 22 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 12a8c69..7c7f8c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 3.2.2-rc.0 +- Add ImageKnifeComponent to destroy network request interruption +- Code refactoring during the download of image resources stage + ## 3.2.1 - Release official version diff --git a/entry/src/main/ets/pages/MultipleImageCallBack.ets b/entry/src/main/ets/pages/MultipleImageCallBack.ets index c052a5a..6f206c9 100644 --- a/entry/src/main/ets/pages/MultipleImageCallBack.ets +++ b/entry/src/main/ets/pages/MultipleImageCallBack.ets @@ -108,7 +108,7 @@ struct MultipleImageCallBack { console.log('image load multiple loadFail:' + this.failIndex) }, onLoadCancel:(message,request)=>{ - let flag = request?.imageKnifeData?.type ? true : false + let flag = request?.imageKnifeData?.timeInfo?.netRequestStartTime ? true : false if (flag) { this.cancelLoadIndex++ } else { diff --git a/library/src/main/ets/ImageKnife.ets b/library/src/main/ets/ImageKnife.ets index 50a4ef4..277eac4 100644 --- a/library/src/main/ets/ImageKnife.ets +++ b/library/src/main/ets/ImageKnife.ets @@ -25,6 +25,7 @@ import { util } from '@kit.ArkTS'; import { image } from '@kit.ImageKit'; import { common } from '@kit.AbilityKit'; import { LogUtil } from './utils/LogUtil'; +import { emitter } from '@kit.BasicServicesKit'; export class ImageKnife { @@ -177,6 +178,9 @@ export class ImageKnife { */ cancel(request:ImageKnifeRequest) { request.requestState = ImageKnifeRequestState.DESTROY + if (typeof request.imageKnifeOption.loadSrc === 'string') { + emitter.emit(request.imageKnifeOption.loadSrc + request.componentId) + } } /** * 预加载图片到文件缓存 diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index 573846a..49943e7 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -356,22 +356,42 @@ export class ImageKnifeDispatcher { if (pixelmap === undefined) { this.executingJobMap.remove(memoryKey); requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { - requestWithSource.request.requestState = ImageKnifeRequestState.ERROR - LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail) - // 回调请求失败 - if (requestWithSource.source === ImageKnifeRequestSource.SRC && - requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined && - requestJobResult.loadFail) { - this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData, requestWithSource.request) - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request); - } - if (requestWithSource.source === ImageKnifeRequestSource.SRC && - requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) { - requestWithSource.request.requestState = ImageKnifeRequestState.PROGRESS - if (this.showFromMemomry(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, - ImageKnifeRequestSource.ERROR_HOLDER) === false) { - this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, - ImageKnifeRequestSource.ERROR_HOLDER); + if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) { + requestWithSource.request.requestState = ImageKnifeRequestState.ERROR + LogUtil.error('getAndShowImage_CallBack.pixelmap failed:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion + " error: " + requestJobResult.loadFail) + // 回调请求失败 + if (requestWithSource.source === ImageKnifeRequestSource.SRC && + requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined && + requestJobResult.loadFail) { + this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, requestJobResult.imageKnifeData, requestWithSource.request) + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail,requestWithSource.request); + } + if (requestWithSource.source === ImageKnifeRequestSource.SRC && + requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) { + requestWithSource.request.requestState = ImageKnifeRequestState.PROGRESS + if (this.showFromMemomry(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, + ImageKnifeRequestSource.ERROR_HOLDER) === false) { + this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, + ImageKnifeRequestSource.ERROR_HOLDER); + } + } + } else { + if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) { + // 回调请求成功 + // 回调请求成功 + //设置失败回调的时间点 + let callBackData = requestWithSource.request.imageKnifeData; + + if (requestJobResult.imageKnifeData && requestJobResult.imageKnifeData.timeInfo) { + requestJobResult.imageKnifeData.timeInfo.requestCancelTime = Date.now(); + if (requestJobResult.imageKnifeData.errorInfo) { + requestJobResult.imageKnifeData.errorInfo.phase = LoadPhase.PHASE_WILL_SHOW; + requestJobResult.imageKnifeData.errorInfo.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE; + } + } + 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(requestJobResult.loadFail ?? 'component has destroyed from load', requestWithSource.request) } } }); @@ -420,7 +440,7 @@ export class ImageKnifeDispatcher { } // 保存内存缓存 - if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) { + if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File && currentRequest.requestState !== ImageKnifeRequestState.DESTROY) { LogUtil.log('getAndShowImage_saveMemoryCache.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion) ImageKnife.getInstance() .saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight), @@ -454,6 +474,9 @@ export class ImageKnifeDispatcher { requestWithSource.request.requestState = ImageKnifeRequestState.ERROR; } } else { + if (typeof currentRequest.imageKnifeData?.source !== 'string') { + (currentRequest.imageKnifeData?.source as PixelMap).release() + } if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) { // 回调请求成功 // 回调请求成功 diff --git a/library/src/main/ets/components/ImageKnifeComponent.ets b/library/src/main/ets/components/ImageKnifeComponent.ets index 2cad1ea..e31c6f9 100644 --- a/library/src/main/ets/components/ImageKnifeComponent.ets +++ b/library/src/main/ets/components/ImageKnifeComponent.ets @@ -20,6 +20,7 @@ import { LogUtil } from '../utils/LogUtil'; import { ImageKnifeData, ImageKnifeRequestSource } from '../model/ImageKnifeData'; import { IEngineKey } from '../key/IEngineKey'; import { DefaultEngineKey } from '../key/DefaultEngineKey'; +import { emitter } from '@kit.BasicServicesKit'; @Component export struct ImageKnifeComponent { @@ -29,6 +30,7 @@ export struct ImageKnifeComponent { @State adaptiveWidth: Length = '100%' @State adaptiveHeight: Length | undefined = '100%' @State objectFit: ImageFit = ImageFit.Contain + private componentId: number = this.getUniqueId() private request: ImageKnifeRequest | undefined private lastWidth: number = 0 private lastHeight: number = 0 @@ -65,13 +67,21 @@ export struct ImageKnifeComponent { } aboutToDisappear(): void { + this.emitterDestroy() this.clearLastRequest() } aboutToRecycle() { this.pixelMap = ImageContent.EMPTY + this.emitterDestroy() this.clearLastRequest() } + + emitterDestroy() { + if (typeof this.imageKnifeOption.loadSrc === 'string') { + emitter.emit(this.imageKnifeOption.loadSrc + this.componentId) + } + } /** * 对已DESTROY的组件不再发起请求 */ @@ -105,13 +115,13 @@ export struct ImageKnifeComponent { ' loadSrc = ' + this.imageKnifeOption.loadSrc + ' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc + ' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc + - ' componentId = ' + this.getUniqueId()) + ' componentId = ' + this.componentId) if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize) { this.isImageFitAutoResize = false } else { ImageKnife.getInstance().execute(this.getRequest( - this.currentWidth, this.currentHeight, this.getUniqueId())) + this.currentWidth, this.currentHeight, this.componentId)) } } } @@ -127,9 +137,9 @@ export struct ImageKnifeComponent { ' loadSrc = ' + this.imageKnifeOption.loadSrc + ' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc + ' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc + - ' componentId = ' + this.getUniqueId()) + ' componentId = ' + this.componentId) ImageKnife.getInstance().execute(this.getRequest( - this.currentWidth, this.currentHeight, this.getUniqueId())) + this.currentWidth, this.currentHeight, this.componentId)) } getCurrentContext(): common.UIAbilityContext { diff --git a/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets b/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets index 83c802d..46c7221 100644 --- a/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets +++ b/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets @@ -61,6 +61,10 @@ export class HttpLoaderStrategy implements IImageLoaderStrategy { ${request.componentVersion}`); callBackTimeInfo.netRequestStartTime = Date.now(); const httpRequest = http.createHttp(); + emitter.on((request.src as string) + request.componentId,()=>{ + emitter.off((request.src as string) + request.componentId) + httpRequest.destroy() + }) let progress: number = 0; const arrayBuffers: ArrayBuffer[] = []; const headerObj: Record = ImageKnifeLoader.getHeaderObj(request);