1.修改imageknifeOpion为小写
2.writeCacheStrategy为memory时,子线程不写文件 3.文件缓存未初始化时,不写缓存 Signed-off-by: madixin <madixin@huawei.com>
This commit is contained in:
parent
00f5e81571
commit
33ba458600
|
@ -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<HeaderOptions> | 全局设置http请求头 |
|
||||
| deleteHeader | key: string | 全局删除http请求头 |
|
||||
| setEngineKeyImpl | CustomEngineKeyImpl | 全局配置缓存key |
|
||||
| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 |
|
||||
|
||||
## 约束与限制
|
||||
在下述版本验证通过:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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<ImageKnifeRequestWithSource> | 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<RequestJobResult
|
|||
});
|
||||
|
||||
// 保存文件缓存
|
||||
if (resBuf !== undefined) {
|
||||
if (resBuf !== undefined && request.writeCacheStrategy !== WriteCacheStrategyType.Memory) {
|
||||
let copyBuf = buffer.concat([buffer.from(resBuf)]).buffer; // IDE有bug,不能直接获取resBuf.byteLength
|
||||
bufferSize = copyBuf.byteLength
|
||||
FileCache.saveFileCacheOnlyFile(request.context, request.key, resBuf)
|
||||
|
@ -324,7 +325,6 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
|
|||
}
|
||||
}
|
||||
} else if ((request.src as Resource).id !== undefined) { //从资源文件获取
|
||||
resBuf = FileCache.getFileCacheByFile(request.context, request.key)
|
||||
if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == 0) {
|
||||
resBuf = request.context.resourceManager.getMediaContentSync((request.src as Resource).id).buffer as ArrayBuffer
|
||||
} else if (resBuf == undefined && request.requestSource != 0) {
|
||||
|
@ -401,4 +401,5 @@ interface RequestJobRequest {
|
|||
onlyRetrieveFromCache?: boolean
|
||||
requestSource:ImageKnifeRequestSource
|
||||
transformation?: PixelMapTransformation
|
||||
writeCacheStrategy?: WriteCacheStrategyType
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ export class ImageKnifeRequest {
|
|||
requestState: ImageKnifeRequestState = ImageKnifeRequestState.PROGRESS
|
||||
componentWidth: number = 0
|
||||
componentHeight: number = 0
|
||||
ImageKnifeOption: ImageKnifeOption
|
||||
imageKnifeOption: ImageKnifeOption
|
||||
context: common.UIAbilityContext
|
||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback
|
||||
componentVersion: number = 0
|
||||
|
@ -36,7 +36,7 @@ export class ImageKnifeRequest {
|
|||
height: number,
|
||||
version: number,
|
||||
ImageKnifeRequestCallback: ImageKnifeRequestCallback) {
|
||||
this.ImageKnifeOption = option
|
||||
this.imageKnifeOption = option
|
||||
this.context = uIAbilityContext
|
||||
this.componentWidth = width
|
||||
this.componentHeight = height
|
||||
|
|
|
@ -27,9 +27,9 @@ export class DefaultJobQueue implements IJobQueue {
|
|||
}
|
||||
|
||||
add(request: ImageKnifeRequest): void {
|
||||
if (request.ImageKnifeOption.priority === undefined || request.ImageKnifeOption.priority === taskpool.Priority.MEDIUM) {
|
||||
if (request.imageKnifeOption.priority === undefined || request.imageKnifeOption.priority === taskpool.Priority.MEDIUM) {
|
||||
this.normalQueue.add(request)
|
||||
} else if (request.ImageKnifeOption.priority === taskpool.Priority.HIGH) {
|
||||
} else if (request.imageKnifeOption.priority === taskpool.Priority.HIGH) {
|
||||
this.highQueue.add(request)
|
||||
} else {
|
||||
this.lowQueue.add(request)
|
||||
|
|
|
@ -31,7 +31,7 @@ export class FileCache {
|
|||
maxSize: number = 0
|
||||
path: string = ""
|
||||
private lruCache: util.LRUCache<string, number>
|
||||
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<void> {
|
||||
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)
|
||||
|
|
Loading…
Reference in New Issue