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..ff79a5b 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 { @@ -176,6 +177,9 @@ export class ImageKnife { * @param request 图片请求request */ cancel(request:ImageKnifeRequest) { + if (typeof request?.imageKnifeOption.loadSrc === 'string' && !request?.drawMainSuccess) { + emitter.emit(request.imageKnifeOption.loadSrc + request.componentId) + } request.requestState = ImageKnifeRequestState.DESTROY } /** @@ -462,12 +466,12 @@ export class ImageKnife { return false } - async execute(request: ImageKnifeRequest,isAnimator?: boolean): Promise { + async execute(request: ImageKnifeRequest): Promise { LogUtil.log('ImageKnife_DataTime_execute.start:'+request.imageKnifeOption.loadSrc) if (this.headerMap.size > 0) { request.addHeaderMap(this.headerMap) } - this.dispatcher.enqueue(request,isAnimator) + this.dispatcher.enqueue(request) LogUtil.log('ImageKnife_DataTime_execute.end:'+request.imageKnifeOption.loadSrc) } diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index 573846a..da4ada1 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -87,6 +87,7 @@ export class ImageKnifeDispatcher { if (requestSource == ImageKnifeRequestSource.SRC) { request.requestState = ImageKnifeRequestState.COMPLETE + request.drawMainSuccess = true // 回调请求开结束 if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) { this.copyMemoryCacheInfo(memoryCache, request.imageKnifeData); @@ -150,11 +151,11 @@ export class ImageKnifeDispatcher { request.imageKnifeData = callBackData; } - enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void { + enqueue(request: ImageKnifeRequest,): void { //初始化加载回调信息 this.initCallData(request); //1.内存有的话直接渲染 - if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) { + if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator)) { return } // 2.内存获取占位图 @@ -168,18 +169,20 @@ export class ImageKnifeDispatcher { this.jobQueue.add(request) return } - this.executeJob(request,isAnimator) + this.executeJob(request) } - executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void { + executeJob(request: ImageKnifeRequest): void { LogUtil.log('executeJob.start:' + request.componentId + ',version:' + request.componentVersion) // 加载占位符 if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) { this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) } - + if (request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { + request.imageKnifeOption.onLoadListener?.onLoadStart(request) + } // 加载主图 - this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator) + this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,request.animator) LogUtil.log('executeJob.end:' + request.componentId + ',version:' + request.componentVersion) } @@ -188,9 +191,6 @@ export class ImageKnifeDispatcher { */ getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void { LogUtil.log('getAndShowImage.start:' + currentRequest.componentId + ',srcType:' + requestSource + ',version:' + currentRequest.componentVersion) - if (requestSource === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { - currentRequest.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest) - } let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator, currentRequest.componentWidth, currentRequest.componentHeight) let requestList: List | undefined = this.executingJobMap.get(memoryKey) @@ -353,17 +353,64 @@ export class ImageKnifeDispatcher { } let pixelmap = requestJobResult.pixelMap; + // 请求取消 + if (currentRequest.requestState === ImageKnifeRequestState.DESTROY) { + this.executingJobMap.remove(memoryKey); + requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { + if (currentRequest.componentId !== requestWithSource.request.componentId && requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) { + // 加载占位符 + if (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && + requestWithSource.request.imageKnifeOption.placeholderSrc !== undefined && + requestWithSource.request.drawPlayHolderSuccess == false) { + this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) + } else if (requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER && + requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) { + this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) + } else if (requestWithSource.source === ImageKnifeRequestSource.SRC) { + // 加载主图 + this.getAndShowImage(requestWithSource.request, requestWithSource.request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,requestWithSource.request.animator) + } + } else { + if (pixelmap !== undefined && typeof pixelmap !== 'string') { + (pixelmap as PixelMap).release() + } + 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) + } + } + }) + this.dispatchNextJob() + return + } + // 请求失败 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) + 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); + 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) { @@ -412,8 +459,8 @@ export class ImageKnifeDispatcher { //构建缓存保存的ImageKnifeData let saveCacheImageData: ImageKnifeData = { source: pixelmap!, - imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width, - imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height, + imageWidth: requestJobResult.size?.width ?? 0, + imageHeight: requestJobResult.size?.height ?? 0, type: requestJobResult.type, bufSize: requestJobResult.bufferSize, imageAnimator: imageKnifeData.imageAnimator @@ -430,50 +477,31 @@ export class ImageKnifeDispatcher { if (requestList !== undefined) { // key相同的request,一起绘制 requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { - if (requestWithSource.request.requestState !== ImageKnifeRequestState.DESTROY) { - // 画主图 - if (requestWithSource.source === ImageKnifeRequestSource.SRC || - requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER - || (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && - requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) { - requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion, - imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight }, - requestWithSource.source, imageKnifeData.imageAnimator); - } + // 画主图 + if (requestWithSource.source === ImageKnifeRequestSource.SRC || + requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER + || (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && + requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) { + requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion, + imageKnifeData.source, { width: imageKnifeData.imageWidth, height: imageKnifeData.imageHeight }, + requestWithSource.source, imageKnifeData.imageAnimator); + } - if (requestWithSource.source == ImageKnifeRequestSource.SRC) { - requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE; - if (requestWithSource.request.imageKnifeOption.onLoadListener && - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) { - // 回调请求成功 - this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData,requestWithSource.request); - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source, - saveCacheImageData, requestWithSource.request); - } - } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { - requestWithSource.request.requestState = ImageKnifeRequestState.ERROR; - } - } else { - if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) { + if (requestWithSource.source == ImageKnifeRequestSource.SRC) { + requestWithSource.request.requestState = ImageKnifeRequestState.COMPLETE; + requestWithSource.request.drawMainSuccess = true + if (requestWithSource.request.imageKnifeOption.onLoadListener && + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) { // 回调请求成功 - // 回调请求成功 - //设置失败回调的时间点 - 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('component has destroyed from load', requestWithSource.request) + this.assembleImageKnifeData(requestWithSource.request.imageKnifeData, imageKnifeData, + requestWithSource.request); + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source, + saveCacheImageData, requestWithSource.request); } + } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { + requestWithSource.request.requestState = ImageKnifeRequestState.ERROR; } }); - this.executingJobMap.remove(memoryKey); this.dispatchNextJob(); } else { diff --git a/library/src/main/ets/components/ImageKnifeAnimatorComponent.ets b/library/src/main/ets/components/ImageKnifeAnimatorComponent.ets index a88e775..ff311ad 100644 --- a/library/src/main/ets/components/ImageKnifeAnimatorComponent.ets +++ b/library/src/main/ets/components/ImageKnifeAnimatorComponent.ets @@ -18,6 +18,7 @@ import common from '@ohos.app.ability.common'; import { ImageKnife } from '../ImageKnife'; import { LogUtil } from '../utils/LogUtil'; import { ImageKnifeRequestSource } from '../model/ImageKnifeData'; +import { emitter } from '@kit.BasicServicesKit'; @Component export struct ImageKnifeAnimatorComponent { @@ -26,11 +27,13 @@ export struct ImageKnifeAnimatorComponent { @State pixelMap: PixelMap | string | undefined = undefined @State imageAnimator: Array | undefined = undefined @State adaptiveWidth: Length = '100%' - @State adaptiveHeight: Length = '100%' + @State adaptiveHeight: Length | undefined = '100%' @State objectFit: ImageFit = ImageFit.Contain + private componentId: number = 0 private request: ImageKnifeRequest | undefined private lastWidth: number = 0 private lastHeight: number = 0 + private isImageFitAutoResize: boolean = false private currentWidth: number = 0 private currentHeight: number = 0 private componentVersion: number = 0 @@ -38,23 +41,33 @@ export struct ImageKnifeAnimatorComponent { aboutToAppear(): void { this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit + this.componentId = this.getUniqueId() } aboutToDisappear(): void { - if (this.request !== undefined) { - this.request.requestState = ImageKnifeRequestState.DESTROY - this.request = undefined - } + this.emitterDestroy() + this.clearLastRequest() } aboutToRecycle() { + this.emitterDestroy() + this.clearLastRequest() + } + + emitterDestroy() { + if (typeof this.request?.imageKnifeOption.loadSrc === 'string' && !this.request?.drawMainSuccess) { + emitter.emit(this.request.imageKnifeOption.loadSrc + this.componentId) + } + } + /** + * 对已DESTROY的组件不再发起请求 + */ + private clearLastRequest(){ if (this.request !== undefined) { this.request.requestState = ImageKnifeRequestState.DESTROY this.request = undefined } - this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit } - build() { ImageAnimator() .images(this.imageAnimator) @@ -79,8 +92,14 @@ export struct ImageKnifeAnimatorComponent { ' loadSrc = ' + this.imageKnifeOption.loadSrc + ' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc + ' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc + - ' componentId = ' + this.getUniqueId()) - ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true) + ' 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.componentId)) + } } } }) @@ -92,17 +111,17 @@ export struct ImageKnifeAnimatorComponent { } watchImageKnifeOption() { - if (this.request !== undefined) { - this.request.requestState = ImageKnifeRequestState.DESTROY - } - this.request = undefined + this.clearLastRequest() this.componentVersion++ + this.isImageFitAutoResize = false + this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit LogUtil.log('watchImageKnifeOption execute request:width=' + this.currentWidth + ' height= ' + this.currentHeight + ' loadSrc = ' + this.imageKnifeOption.loadSrc + ' placeholderSrc = ' + this.imageKnifeOption.placeholderSrc + ' errorholderSrc = ' + this.imageKnifeOption.errorholderSrc + - ' componentId = ' + this.getUniqueId()) - ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight),true) + ' componentId = ' + this.componentId) + ImageKnife.getInstance().execute(this.getRequest( + this.currentWidth, this.currentHeight, this.componentId)) } getCurrentContext(): common.UIAbilityContext { @@ -112,43 +131,52 @@ export struct ImageKnifeAnimatorComponent { return this.currentContext } - getRequest(width: number, height: number): ImageKnifeRequest { - if (this.request == undefined) { - this.request = new ImageKnifeRequest( - this.imageKnifeOption, - this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(), - width, - height, - this.componentVersion, - { - showPixelMap: (version: number, pixelMap: PixelMap | string,size: Size, requestSource: ImageKnifeRequestSource,imageAnimator?: Array) => { - if (version !== this.componentVersion) { - return //针对reuse场景,不显示历史图片 - } - if (imageAnimator != undefined) { - this.imageAnimator = imageAnimator - } else { - this.imageAnimator = [ - { - src: pixelMap - } - ] - } - - if (requestSource == ImageKnifeRequestSource.SRC) { - this.objectFit = - this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit - } else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) { - this.objectFit = - this.imageKnifeOption.placeholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.placeholderObjectFit - } else { - this.objectFit = - this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit - } + getRequest(width: number, height: number,componentId: number): ImageKnifeRequest { + this.request = new ImageKnifeRequest( + this.imageKnifeOption, + this.imageKnifeOption.context !== undefined ? this.imageKnifeOption.context : this.getCurrentContext(), + width, + height, + this.componentVersion, + { + showPixelMap: (version: number, pixelMap: PixelMap | string, size: Size, requestSource: ImageKnifeRequestSource, + imageAnimator?: Array) => { + if (version !== this.componentVersion) { + return //针对reuse场景,不显示历史图片 + } + if (imageAnimator != undefined) { + this.imageAnimator = imageAnimator + } else { + this.imageAnimator = [ + { + src: pixelMap + } + ] } - }) - } + if (this.imageKnifeOption.objectFit === ImageFit.Auto && this.isImageFitAutoResize == false && + requestSource == ImageKnifeRequestSource.SRC) { + this.adaptiveHeight = undefined + this.isImageFitAutoResize = true + } + + if (requestSource == ImageKnifeRequestSource.SRC) { + this.objectFit = + this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit + } else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) { + this.objectFit = + this.imageKnifeOption.placeholderObjectFit === undefined ? + (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : + this.imageKnifeOption.placeholderObjectFit + } else { + this.objectFit = + this.imageKnifeOption.errorholderObjectFit === undefined ? + (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : + this.imageKnifeOption.errorholderObjectFit + } + } + }) + this.request.animator = true return this.request } } \ No newline at end of file diff --git a/library/src/main/ets/components/ImageKnifeComponent.ets b/library/src/main/ets/components/ImageKnifeComponent.ets index 2cad1ea..6dd0407 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 = 0 private request: ImageKnifeRequest | undefined private lastWidth: number = 0 private lastHeight: number = 0 @@ -40,7 +42,7 @@ export struct ImageKnifeComponent { aboutToAppear(): void { this.objectFit = (this.imageKnifeOption.objectFit === undefined || this.imageKnifeOption.objectFit === ImageFit.Auto) ? ImageFit.Contain : this.imageKnifeOption.objectFit - + this.componentId = this.getUniqueId() if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片 let engineKey: IEngineKey = new DefaultEngineKey(); let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance() @@ -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.request?.imageKnifeOption.loadSrc === 'string' && !this.request?.drawMainSuccess) { + emitter.emit(this.request.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..bbc1dec 100644 --- a/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets +++ b/library/src/main/ets/loaderStrategy/HttpLoaderStrategy.ets @@ -61,6 +61,9 @@ export class HttpLoaderStrategy implements IImageLoaderStrategy { ${request.componentVersion}`); callBackTimeInfo.netRequestStartTime = Date.now(); const httpRequest = http.createHttp(); + emitter.once((request.src as string) + request.componentId,()=>{ + httpRequest.destroy() + }) let progress: number = 0; const arrayBuffers: ArrayBuffer[] = []; const headerObj: Record = ImageKnifeLoader.getHeaderObj(request); @@ -95,13 +98,12 @@ export class HttpLoaderStrategy implements IImageLoaderStrategy { 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, + connectTimeout: request.connectTimeout ?? 60000, + readTimeout: request.readTimeout ?? 30000, caPath: request.caPath }); promise.then((data: number) => { + emitter.off((request.src as string) + request.componentId) callBackData.httpCode = data; ImageKnifeLoader.assembleError(callBackData,LoadPhase.PHASE_NET, undefined); callBackTimeInfo.netRequestEndTime = Date.now(); @@ -114,6 +116,7 @@ export class HttpLoaderStrategy implements IImageLoaderStrategy { LoadPhase.PHASE_NET, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE)); } }).catch((err: BusinessError) => { + emitter.off((request.src as string) + request.componentId) callBackData.httpCode = err.code; loadError = 'HttpDownloadClient download ERROR : err = ' + JSON.stringify(err); callBackTimeInfo.netRequestEndTime = Date.now(); diff --git a/library/src/main/ets/model/ImageKnifeRequest.ets b/library/src/main/ets/model/ImageKnifeRequest.ets index ff00e2d..5f55c78 100644 --- a/library/src/main/ets/model/ImageKnifeRequest.ets +++ b/library/src/main/ets/model/ImageKnifeRequest.ets @@ -22,6 +22,7 @@ export class ImageKnifeRequest { componentWidth: number = 0 componentHeight: number = 0 drawPlayHolderSuccess: boolean = false + drawMainSuccess: boolean = false imageKnifeOption: ImageKnifeOption context: common.UIAbilityContext ImageKnifeRequestCallback: ImageKnifeRequestCallback @@ -29,6 +30,7 @@ export class ImageKnifeRequest { headers: Map = new Map() imageKnifeData?: ImageKnifeData componentId?: number + animator?: boolean constructor(option: ImageKnifeOption, uIAbilityContext: common.UIAbilityContext, width: number,