跳过网络,从内存中取图片
This commit is contained in:
parent
04cfeb18fa
commit
17ddf94052
|
@ -354,6 +354,14 @@ struct IndexFunctionDemo {
|
|||
router.pushUrl({ url: 'pages/testImageKnifeHttpRequestHeader' });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
|
||||
Text('测试图片缓存内存').fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button('测试图片缓存内存')
|
||||
.onClick(() => {
|
||||
router.pushUrl({ url: 'pages/testImageKnifeCache' });
|
||||
}).margin({ top: 5, left: 3 })
|
||||
}.width('100%').height(60).backgroundColor(Color.Pink)
|
||||
}
|
||||
}
|
||||
.width('100%')
|
||||
|
|
|
@ -44,6 +44,8 @@
|
|||
"pages/testImageKnifeAutoPage",
|
||||
"pages/testImageKnifeAutoWidthPage",
|
||||
"pages/testImageKnifeAutoHeightPage",
|
||||
"pages/testReusePhotoPage"
|
||||
"pages/testReusePhotoPage",
|
||||
"pages/testImageKnifeCache"
|
||||
|
||||
]
|
||||
}
|
|
@ -16,7 +16,7 @@
|
|||
import { DiskLruCache } from "../cache/DiskLruCache"
|
||||
import { EngineKeyFactories } from "../cache/key/EngineKeyFactories"
|
||||
import { EngineKeyInterface } from "../cache/key/EngineKeyInterface"
|
||||
import { RequestOption, Size } from "../imageknife/RequestOption"
|
||||
import { CacheType, RequestOption, Size } from "../imageknife/RequestOption"
|
||||
import { AsyncCallback } from "../imageknife/interface/AsyncCallback"
|
||||
import { PlaceHolderManager } from "../imageknife/holder/PlaceHolderManager"
|
||||
import { RetryHolderManager } from "../imageknife/holder/RetryHolderManager"
|
||||
|
@ -48,6 +48,10 @@ import { MemoryCacheProxy } from './requestmanage/MemoryCacheProxy'
|
|||
import { ObjectKey } from './ObjectKey'
|
||||
import { TaskParams } from './TaskParams'
|
||||
import { Constants } from './constants/Constants'
|
||||
import { GIFParseImpl } from './utils/gif/GIFParseImpl'
|
||||
import { SVGParseImpl } from './utils/svg/SVGParseImpl'
|
||||
import { ParseImageUtil } from './utils/ParseImageUtil'
|
||||
import { IParseImage } from './interface/IParseImage'
|
||||
|
||||
export class ImageKnife {
|
||||
static readonly SEPARATOR: string = '/'
|
||||
|
@ -77,9 +81,10 @@ export class ImageKnife {
|
|||
defaultLifeCycle: IDrawLifeCycle | undefined = undefined;
|
||||
// 开发者可配置全局缓存
|
||||
engineKeyImpl: EngineKeyInterface;
|
||||
private mParseImageUtil: IParseImage<PixelMap>;
|
||||
|
||||
private constructor() {
|
||||
|
||||
this.mParseImageUtil = new ParseImageUtil();
|
||||
this.runningMaps = new EasyLinkedHashMap();
|
||||
this.pendingMaps = new EasyLinkedHashMap();
|
||||
this.pausedMaps = new EasyLinkedHashMap();
|
||||
|
@ -321,6 +326,91 @@ export class ImageKnife {
|
|||
return this.parseSource(request);
|
||||
}
|
||||
|
||||
|
||||
public isUrlExist(request: RequestOption): Promise<ImageKnifeData> {
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
this.generateDataCacheKey(request);
|
||||
let loadComplete = (imageKnifeData: ImageKnifeData) => {
|
||||
resolve(imageKnifeData);
|
||||
}
|
||||
let loadError = (err ?: BusinessError | string) => {
|
||||
reject(undefined);
|
||||
}
|
||||
this.loadMemoryCacheAndDiskFrom(request, loadComplete, loadError);
|
||||
})
|
||||
}
|
||||
|
||||
loadMemoryCacheAndDiskFrom(request: RequestOption, onComplete: (imageKnifeData: ImageKnifeData) => void | PromiseLike<ImageKnifeData>, onError: (err?: BusinessError | string) => void) {
|
||||
|
||||
if (request.cacheType == CacheType.Cache) {
|
||||
|
||||
let cache = this.memoryCacheProxy.loadMemoryCache(request.generateCacheKey, true);
|
||||
if (cache == null || typeof cache == 'undefined') {
|
||||
onError("No data in cache!")
|
||||
}else {
|
||||
cache.waitSaveDisk = false;
|
||||
//2.网络缓存有数据,返回
|
||||
onComplete(cache);
|
||||
}
|
||||
|
||||
}else if (request.cacheType == CacheType.Disk){
|
||||
let cached: ArrayBuffer = DiskLruCache.getFileCacheByFile((ImageKnifeGlobal.getInstance()
|
||||
.getHapContext() as common.UIAbilityContext).filesDir as string, request.generateDataKey) as ArrayBuffer;
|
||||
|
||||
if (cached != null) {
|
||||
|
||||
let filetype: string | null = this.fileTypeUtil.getFileType(cached);
|
||||
|
||||
if (filetype == null) {
|
||||
onError('请检查数据源');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.fileTypeUtil.isImage(cached)) {
|
||||
onError('暂不支持的类型!类型=' + filetype);
|
||||
}
|
||||
|
||||
if (ImageKnifeData.GIF == filetype && !request.dontAnimateFlag) {
|
||||
let gifParseImpl = new GIFParseImpl()
|
||||
gifParseImpl.parseGifs(cached, (data?: GIFFrame[], err?: BusinessError | string) => {
|
||||
if (err) {
|
||||
onError(err)
|
||||
}
|
||||
LogUtil.log("gifProcess data is null:" + (data == null));
|
||||
if (!!data) {
|
||||
let imageKnifeData = ImageKnifeData.createImageGIFFrame(ImageKnifeType.GIFFRAME, data);
|
||||
LogUtil.log('gifProcess 生成gif 返回数据类型')
|
||||
onComplete(imageKnifeData)
|
||||
} else {
|
||||
onError('Parse GIF callback data is null, you need check callback data!')
|
||||
}
|
||||
})
|
||||
|
||||
} else if (ImageKnifeData.SVG == filetype) {
|
||||
let svgParseImpl = new SVGParseImpl()
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
svgParseImpl.parseSvg(request, cached, success, onError)
|
||||
} else {
|
||||
//5.磁盘有数据,解析错误返回onError
|
||||
let success = (value: PixelMap) => {
|
||||
let imageKnifeData = ImageKnifeData.createImagePixelMap(ImageKnifeType.PIXELMAP, value);
|
||||
onComplete(imageKnifeData);
|
||||
}
|
||||
this.mParseImageUtil.parseImage(cached, success, onError)
|
||||
}
|
||||
|
||||
} else {
|
||||
//6.磁盘无数据,返回onError
|
||||
onError("No data in disk cache!")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
generateDataCacheKey(request: RequestOption) {
|
||||
let factories: EngineKeyInterface;
|
||||
let cacheKey: string;
|
||||
|
@ -588,10 +678,10 @@ export class ImageKnife {
|
|||
retryholderSrc: request.retryholderSrc,
|
||||
});
|
||||
//使用taskpool多线程执行资源下载
|
||||
let task:ESObject = new taskpool.Task(taskExecute, taskParams, loadSrcJson)
|
||||
let task: ESObject = new taskpool.Task(taskExecute, taskParams, loadSrcJson)
|
||||
task.setTransferList([])
|
||||
|
||||
emitter.on(Constants.PROGRESS_EMITTER as ESObject, (data:ESObject) => {
|
||||
emitter.on(Constants.PROGRESS_EMITTER as ESObject, (data: ESObject) => {
|
||||
if (request.progressFunc && data?.data?.value) {
|
||||
let percent = data.data.value as number;
|
||||
request.progressFunc.asyncSuccess(percent);
|
||||
|
|
|
@ -69,6 +69,14 @@ export interface DetachFromLayout {
|
|||
detach: () => void
|
||||
}
|
||||
|
||||
export enum CacheType {
|
||||
//缓存
|
||||
Cache,
|
||||
//磁盘
|
||||
Disk
|
||||
|
||||
}
|
||||
|
||||
export class RequestOption {
|
||||
// 遍历添加图片http请求头
|
||||
headers: Map<string, Object> = new Map<string, Object>();
|
||||
|
@ -83,6 +91,7 @@ export class RequestOption {
|
|||
this.headers = map;
|
||||
}
|
||||
|
||||
cacheType: CacheType = CacheType.Disk;
|
||||
uuid: string = '' // 唯一标识
|
||||
loadSrc: string | PixelMap | Resource = '';
|
||||
strategy: DiskStrategy = new AUTOMATIC();
|
||||
|
@ -186,6 +195,12 @@ export class RequestOption {
|
|||
return this;
|
||||
}
|
||||
|
||||
|
||||
setCacheType(cacheType: CacheType) {
|
||||
this.cacheType = cacheType;
|
||||
return this;
|
||||
}
|
||||
|
||||
getFilesPath() {
|
||||
return this.filesPath;
|
||||
}
|
||||
|
@ -466,10 +481,10 @@ export class RequestOption {
|
|||
}
|
||||
|
||||
// 占位图解析成功
|
||||
placeholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||
placeholderOnComplete = (imageKnifeData: ImageKnifeData) => {
|
||||
LogUtil.log("placeholderOnComplete has called!");
|
||||
LogUtil.log("Main Image is Ready:" + this.loadMainReady);
|
||||
this.setMemoryCache(imageKnifeData,this.placeholderCacheKey);
|
||||
this.setMemoryCache(imageKnifeData, this.placeholderCacheKey);
|
||||
if (!this.loadMainReady && !(this.loadErrorReady || this.loadRetryReady) && !this.loadThumbnailReady) {
|
||||
// 主图未加载成功,并且未加载失败 显示占位图 主图加载成功或者加载失败后=>不展示占位图
|
||||
if (this.placeholderSrc != undefined) {
|
||||
|
@ -501,8 +516,8 @@ export class RequestOption {
|
|||
LogUtil.log("缩略图解析失败 error =" + error)
|
||||
}
|
||||
// 加载失败 占位图解析成功
|
||||
errorholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||
this.setMemoryCache(imageKnifeData,this.errorholderCacheKey);
|
||||
errorholderOnComplete = (imageKnifeData: ImageKnifeData) => {
|
||||
this.setMemoryCache(imageKnifeData, this.errorholderCacheKey);
|
||||
// 如果有错误占位图 先解析并保存在RequestOption中 等到加载失败时候进行调用
|
||||
this.errorholderData = imageKnifeData;
|
||||
if (this.loadErrorReady) {
|
||||
|
@ -515,8 +530,8 @@ export class RequestOption {
|
|||
errorholderOnError = (error: BusinessError | string) => {
|
||||
LogUtil.log("失败占位图解析失败 error =" + error)
|
||||
}
|
||||
retryholderOnComplete = (imageKnifeData:ImageKnifeData) => {
|
||||
this.setMemoryCache(imageKnifeData,this.retryholderCacheKey);
|
||||
retryholderOnComplete = (imageKnifeData: ImageKnifeData) => {
|
||||
this.setMemoryCache(imageKnifeData, this.retryholderCacheKey);
|
||||
this.retryholderData = imageKnifeData;
|
||||
if (this.loadRetryReady) {
|
||||
if (this.retryholderFunc != undefined) {
|
||||
|
@ -528,7 +543,7 @@ export class RequestOption {
|
|||
LogUtil.log("重试占位图解析失败 error =" + error)
|
||||
}
|
||||
loadComplete = (imageKnifeData: ImageKnifeData) => {
|
||||
this.setMemoryCache(imageKnifeData,this.generateCacheKey);
|
||||
this.setMemoryCache(imageKnifeData, this.generateCacheKey);
|
||||
if (typeof this.loadSrc == 'string') {
|
||||
this.setDiskCache();
|
||||
}
|
||||
|
@ -584,7 +599,7 @@ export class RequestOption {
|
|||
}
|
||||
}
|
||||
//设置内存缓存
|
||||
setMemoryCache = (imageKnifeData: ImageKnifeData,cacheKey:string) => {
|
||||
setMemoryCache = (imageKnifeData: ImageKnifeData, cacheKey: string) => {
|
||||
|
||||
let memoryCacheProxy = ImageKnifeGlobal.getInstance()
|
||||
.getImageKnife()?.getMemoryCacheProxy() as MemoryCacheProxy<string, ImageKnifeData>;
|
||||
|
|
Loading…
Reference in New Issue