diff --git a/README.md b/README.md index 0c1ef1c..c329bfe 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ 本项目参考开源库 [Glide](https://github.com/bumptech/glide) 进行OpenHarmony的自研版本: -- 支持自定义内存缓存策略,支持设置内存缓存的大小。 +- 支持自定义内存缓存策略,支持设置内存缓存的大小(默认LRU策略)。 - 支持磁盘二级缓存,对于下载图片会保存一份至磁盘当中。 - 支持自定义实现图片获取/网络下载 - 支持监听网络下载回调进度 @@ -42,6 +42,9 @@ ## 下载安装 ``` ohpm install @ohos/imageknife + +// 如果需要用文件缓存,需要提前初始化文件缓存 +await ImageKnife.getInstance().initFileCache(context, 256, 256 * 1024 * 1024) ``` ## 使用说明 @@ -162,7 +165,7 @@ ImageKnifeComponent({ ImageKnifeOption: | addHeader | key: string, value: Object | 全局添加http请求头 | | setHeaderOptions | Array | 全局设置http请求头 | | deleteHeader | key: string | 全局删除http请求头 | -| setEngineKeyImpl | CustomEngineKeyImpl | 全局配置缓存key | +| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 | ## 约束与限制 在下述版本验证通过: diff --git a/entry/src/main/ets/pages/ImageTransformation.ets b/entry/src/main/ets/pages/ImageTransformation.ets index 5fd511d..4cbbcba 100644 --- a/entry/src/main/ets/pages/ImageTransformation.ets +++ b/entry/src/main/ets/pages/ImageTransformation.ets @@ -25,12 +25,6 @@ struct ImageTransformation { this.isBlur = value this.upedateImageKnifeOption() }) - .mark({ - strokeColor: Color.Black, - size: 50, - strokeWidth: 5 - }) - .unselectedColor(Color.Red) .width(30) .height(30) Text('模糊效果').fontSize(20) diff --git a/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets b/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets index 8aeb9b6..7816a73 100644 --- a/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets +++ b/entry/src/ohosTest/ets/test/DefaultJobQueueTest.test.ets @@ -54,13 +54,13 @@ export default function DefaultJobQueueTest() { job.add(makeRequest("medium4", getContext() as common.UIAbilityContext)) expect(job.getQueueLength()).assertEqual(7) - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("high1") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium1") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium2") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium3") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("medium4") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("low1") - expect(job.pop()!.ImageKnifeOption.loadSrc).assertEqual("low2") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("high1") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium1") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium2") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium3") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("medium4") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low1") + expect(job.pop()!.imageKnifeOption.loadSrc).assertEqual("low2") expect(job.pop()).assertEqual(undefined) expect(job.getQueueLength()).assertEqual(0) diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index c6295d1..5e2a54f 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -48,7 +48,7 @@ export class ImageKnifeDispatcher { showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): boolean { let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance() - .loadFromMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, request.ImageKnifeOption)) + .loadFromMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, request.imageKnifeOption)) if (memoryCache !== undefined) { // 画主图 if (request.requestState === ImageKnifeRequestState.PROGRESS) { @@ -69,7 +69,7 @@ export class ImageKnifeDispatcher { enqueue(request: ImageKnifeRequest): void { //1.内存有的话直接渲染 - if (this.showFromMemomry(request, request.ImageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC)) { + if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC)) { return } @@ -83,22 +83,22 @@ export class ImageKnifeDispatcher { executeJob(request: ImageKnifeRequest): void { // 加载占位符 - if (request.ImageKnifeOption.placeholderSrc !== undefined) { - if (this.showFromMemomry(request, request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) === false) { - this.getAndShowImage(request, request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) + if (request.imageKnifeOption.placeholderSrc !== undefined) { + if (this.showFromMemomry(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) === false) { + this.getAndShowImage(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) } } // 加载主图 - this.getAndShowImage(request, request.ImageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC) + this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC) } /** * 获取和显示图片 */ getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): void { - let keyMemory: string = this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.ImageKnifeOption) - let keyFile: string = this.engineKeyImpl.generateFileKey(imageSrc, currentRequest.ImageKnifeOption.signature) + let keyMemory: string = this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.imageKnifeOption) + let keyFile: string = this.engineKeyImpl.generateFileKey(imageSrc, currentRequest.imageKnifeOption.signature) let requestList: List | undefined = this.executingJobMap.get(keyMemory) if (requestList == undefined) { requestList = new List() @@ -113,18 +113,19 @@ export class ImageKnifeDispatcher { context: currentRequest.context, src: imageSrc, key: keyFile, - headers:currentRequest.ImageKnifeOption.headerOption, + headers:currentRequest.imageKnifeOption.headerOption, allHeaders:currentRequest.headers, - customGetImage: currentRequest.ImageKnifeOption.customGetImage, - onlyRetrieveFromCache: currentRequest.ImageKnifeOption.onlyRetrieveFromCache, - transformation:currentRequest.ImageKnifeOption.transformation, + customGetImage: currentRequest.imageKnifeOption.customGetImage, + onlyRetrieveFromCache: currentRequest.imageKnifeOption.onlyRetrieveFromCache, + transformation:currentRequest.imageKnifeOption.transformation, + writeCacheStrategy: currentRequest.imageKnifeOption.writeCacheStrategy, requestSource } // 启动线程下载和解码主图 let task = new taskpool.Task(requestJob, request) // 监听网络回调事件 - if (currentRequest.ImageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) { - let progressCallBack = currentRequest.ImageKnifeOption.progressListener + if (currentRequest.imageKnifeOption.progressListener !== undefined && requestSource === ImageKnifeRequestSource.SRC) { + let progressCallBack = currentRequest.imageKnifeOption.progressListener emitter.on(Constants.PROGRESS_EMITTER, (data) => { progressCallBack(data?.data?.value as number) }); @@ -136,10 +137,10 @@ export class ImageKnifeDispatcher { if (pixelmap === undefined) { if (requestList !== undefined) { requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { - if (requestWithSource.source === ImageKnifeRequestSource.SRC && currentRequest.ImageKnifeOption.errorholderSrc !== undefined) { + if (requestWithSource.source === ImageKnifeRequestSource.SRC && currentRequest.imageKnifeOption.errorholderSrc !== undefined) { - if (this.showFromMemomry(currentRequest, currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) === false) { - this.getAndShowImage(currentRequest, currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) + if (this.showFromMemomry(currentRequest, currentRequest.imageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) === false) { + this.getAndShowImage(currentRequest, currentRequest.imageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) } } }); @@ -150,7 +151,7 @@ export class ImageKnifeDispatcher { } } // 保存文件缓存 - if (requestJobResult.bufferSize > 0 && currentRequest.ImageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.Memory) { + if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.Memory) { ImageKnife.getInstance().saveWithoutWriteFile(keyFile, requestJobResult.bufferSize) } @@ -161,9 +162,9 @@ export class ImageKnifeDispatcher { } // 保存内存缓存 - if(currentRequest.ImageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.File) { + if(currentRequest.imageKnifeOption.writeCacheStrategy !== WriteCacheStrategyType.File) { ImageKnife.getInstance() - .saveMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.ImageKnifeOption), + .saveMemoryCache(this.engineKeyImpl.generateMemoryKey(imageSrc, currentRequest.imageKnifeOption), ImageKnifeData) } if (requestList !== undefined) { @@ -305,7 +306,7 @@ async function requestJob(request: RequestJobRequest): Promise - private isInited: boolean = false + static isInited: boolean = false private context?: Context readonly defaultMaxSize: number = 512; readonly defaultSize: number = 128; @@ -57,7 +57,7 @@ export class FileCache { * 遍历缓存文件目录,初始化缓存 */ public async initFileCache() { - if (this.isInited) { + if (FileCache.isInited) { return } @@ -100,7 +100,7 @@ export class FileCache { } this.trimToSize(); - this.isInited = true + FileCache.isInited = true } // 添加缓存键值对,同时写文件 @@ -108,7 +108,7 @@ export class FileCache { if (key == null || value == null) { throw new Error('key or value is invalid '); } - if (!this.isInited) { + if (!FileCache.isInited) { return } @@ -132,7 +132,7 @@ export class FileCache { if (key == null || value == null) { throw new Error('key or value is invalid '); } - if (!this.isInited) { + if (!FileCache.isInited) { return } @@ -151,7 +151,7 @@ export class FileCache { } get(key: string): ArrayBuffer | undefined { - if (!this.isInited) { + if (!FileCache.isInited) { return } @@ -167,7 +167,7 @@ export class FileCache { if (key == null) { throw new Error('key is null,checking the parameter'); } - if (!this.isInited) { + if (!FileCache.isInited) { return } @@ -179,10 +179,10 @@ export class FileCache { } async removeAll(): Promise { - if (!this.isInited) { + if (!FileCache.isInited) { return } - this.isInited = false + FileCache.isInited = false this.lruCache.clear() this.currentMemory = 0; @@ -191,7 +191,7 @@ export class FileCache { await FileUtils.getInstance().deleteFile(this.path + filenames[i]) } - this.isInited = true + FileCache.isInited = true } size(): number { @@ -199,7 +199,7 @@ export class FileCache { } // 移除较少使用的缓存数据 - trimToSize(): void { + private trimToSize(): void { while (true) { if (this.currentMemory <= this.maxMemory || this.lruCache.isEmpty()) { break @@ -242,6 +242,9 @@ export class FileCache { * @param value */ static saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer): boolean { + if (!FileCache.isInited) { + return false + } // 写文件 FileUtils.getInstance() .writeFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key, value)