forked from floraachy/ImageKnife
更新说明:
1、新增自定义key能力 Signed-off-by: 明月清风 <qiufeihu1@h-partners.com>
This commit is contained in:
parent
225754b15d
commit
e65ee6bb81
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -1,6 +1,7 @@
|
|||
## 3.0.0-rc.0
|
||||
使用Image组件替换Canvas组件渲染,并重构大部分的实现逻辑,提升渲染性能
|
||||
|
||||
- 使用Image组件替换Canvas组件渲染,并重构大部分的实现逻辑,提升渲染性能
|
||||
- 补齐自定key特性
|
||||
|
||||
较2.x版本增强点:
|
||||
- 使用Image组件代替Canvas组件渲染
|
||||
- 重构Dispatch分发逻辑,支持控制并发请求数,支持请求排队队列的优先级
|
||||
|
@ -9,7 +10,7 @@
|
|||
- 继承Image的能力,支持option传入border,设置边框,圆角
|
||||
- 继承Image的能力,支持option传入objectFit设置图片缩放
|
||||
- 修复发送消息时最近的两条消息头像闪动的问题
|
||||
|
||||
|
||||
缺失特性
|
||||
- 不支持drawLifeCycle接口,通过canvas自会图片
|
||||
- mainScaleType,border等参数,新版本与系统Image保持一致
|
||||
|
@ -249,12 +250,12 @@
|
|||
|
||||
新增
|
||||
|
||||
- 1.onClick事件属性
|
||||
- 1.onClick事件属性
|
||||
|
||||
删除
|
||||
删除
|
||||
|
||||
- 1.size(设置大小)
|
||||
- 2.sizeAnimated 显式动画
|
||||
- 1.size(设置大小)
|
||||
- 2.sizeAnimated 显式动画
|
||||
- 3.backgroundColor背景色
|
||||
- 4.margin 组件外间距 等属性,删除的属性将由通用属性提供支持,可支持在ImageKnifeComponent自定义组件上链式调用
|
||||
## 1.0.4
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { EngineKeyInterface, ObjectKey } from '@ohos/imageknife';
|
||||
import util from '@ohos.util';
|
||||
import { SparkMD5 } from '@ohos/imageknife/src/main/ets/3rd_party/sparkmd5/spark-md5';
|
||||
|
||||
//全局自定义key demo
|
||||
export class CustomEngineKeyImpl implements EngineKeyInterface {
|
||||
private keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
||||
|
||||
// 生成内存缓存
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let key = "loadSrc=" + this.generateKey(loadSrc) + ";";
|
||||
if (signature) {
|
||||
key += "signature=" + signature.getKey() + ";"
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// key缓存策略,避免无意义的 JSON.stringify
|
||||
private generateKey(key: string | PixelMap | Resource): string {
|
||||
let keyCache = typeof key == "string" ? key : JSON.stringify(key)
|
||||
let result = this.keyCache.get(keyCache)
|
||||
if (result != undefined) {
|
||||
return result
|
||||
} else {
|
||||
result = SparkMD5.hashBinary(keyCache)
|
||||
this.keyCache.put(keyCache, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -17,7 +17,8 @@ import hilog from '@ohos.hilog';
|
|||
import UIAbility from '@ohos.app.ability.UIAbility';
|
||||
import Want from '@ohos.app.ability.Want';
|
||||
import window from '@ohos.window';
|
||||
import { ImageKnife,LogUtil } from '@ohos/imageknife';
|
||||
import { ImageKnife, LogUtil } from '@ohos/imageknife';
|
||||
import { CustomEngineKeyImpl } from '../common/CustomEngineKeyImpl';
|
||||
|
||||
export default class EntryAbility extends UIAbility {
|
||||
onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
|
||||
|
@ -32,9 +33,10 @@ export default class EntryAbility extends UIAbility {
|
|||
// Main window is created, set main page for this ability
|
||||
hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
|
||||
|
||||
LogUtil.mLogLevel = LogUtil.ALL
|
||||
// 初始化ImageKnife的文件缓存
|
||||
await ImageKnife.getInstance().initFileCache(this.context, 256, 256 * 1024 * 1024)
|
||||
LogUtil.mLogLevel = LogUtil.ALL
|
||||
ImageKnife.getInstance().setEngineKeyImpl(new CustomEngineKeyImpl())
|
||||
windowStage.loadContent('pages/Index', (err, data) => {
|
||||
if (err.code) {
|
||||
hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
|
||||
|
|
|
@ -62,7 +62,12 @@ struct Index {
|
|||
|
||||
});
|
||||
})
|
||||
Button("自定义key").margin({top:10}).onClick(()=>{
|
||||
router.push({
|
||||
uri: 'pages/SignatureTestPage',
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
}
|
||||
.width('100%')
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ImageKnifeComponent, ImageKnifeOption, ObjectKey } from '@ohos/imageknife';
|
||||
|
||||
|
||||
@Entry
|
||||
@Component
|
||||
struct SignatureTestPage {
|
||||
@State imageKnifeOption1: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
};
|
||||
@State imageKnifeOption2: ImageKnifeOption =
|
||||
{
|
||||
loadSrc: $r('app.media.icon'),
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
};
|
||||
|
||||
build() {
|
||||
Scroll() {
|
||||
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
|
||||
Text("Signature固定为 1").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption1 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
signature: new ObjectKey("1")
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.imageKnifeOption1 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
|
||||
Text("设置Signature,每次为时间戳").fontSize(15)
|
||||
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
|
||||
Button("加载")
|
||||
.onClick(() => {
|
||||
this.imageKnifeOption2 = {
|
||||
loadSrc: 'https://img-blog.csdn.net/20140514114029140',
|
||||
placeholderSrc:$r("app.media.loading"),
|
||||
signature: new ObjectKey(new Date().getTime().toString())
|
||||
}
|
||||
}).margin({ top: 5, left: 3 })
|
||||
ImageKnifeComponent({ ImageKnifeOption: this.imageKnifeOption2 }).width(300).height(300)
|
||||
}.width('100%').backgroundColor(Color.Pink)
|
||||
}
|
||||
|
||||
}.width('100%')
|
||||
.height('100%')
|
||||
|
||||
}
|
||||
|
||||
aboutToAppear() {
|
||||
console.log("唯一标识页面:" + new ObjectKey(new Date().getTime().toString()).getKey())
|
||||
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
"pages/LongImagePage",
|
||||
"pages/TransformPage",
|
||||
"pages/UserPage",
|
||||
"pages/TestImageFlash"
|
||||
"pages/TestImageFlash",
|
||||
"pages/SignatureTestPage"
|
||||
]
|
||||
}
|
|
@ -10,3 +10,7 @@ export { FileUtils } from './src/main/ets/utils/FileUtils'
|
|||
|
||||
export { LogUtil } from './src/main/ets/utils/LogUtil'
|
||||
|
||||
export { EngineKeyInterface } from './src/main/ets/key/EngineKeyInterface'
|
||||
|
||||
export { ObjectKey } from './src/main/ets/model/ObjectKey'
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import { MemoryLruCache } from './utils/MemoryLruCache';
|
|||
import { IMemoryCache } from './utils/IMemoryCache'
|
||||
import { FileCache } from './utils/FileCache';
|
||||
import { ImageKnifeDispatcher } from './ImageKnifeDispatcher';
|
||||
import { EngineKeyInterface } from './key/EngineKeyInterface';
|
||||
|
||||
|
||||
export class ImageKnife {
|
||||
|
@ -120,4 +121,9 @@ export class ImageKnife {
|
|||
setMaxRequests(concurrency: number): void {
|
||||
this.dispatcher.setMaxRequests(concurrency)
|
||||
}
|
||||
|
||||
setEngineKeyImpl(impl: EngineKeyInterface): void {
|
||||
this.dispatcher.setEngineKeyImpl(impl);
|
||||
}
|
||||
|
||||
}
|
|
@ -31,8 +31,9 @@ import { Constants } from './utils/Constants';
|
|||
import taskpool from '@ohos.taskpool';
|
||||
import { FileTypeUtil } from './utils/FileTypeUtil';
|
||||
import util from '@ohos.util';
|
||||
import { Tools } from './utils/Tools';
|
||||
import { SparkMD5 } from './3rd_party/sparkmd5/spark-md5';
|
||||
import { EngineKeyInterface } from './key/EngineKeyInterface';
|
||||
import { EngineKeyFactories } from './key/EngineKeyFactories';
|
||||
|
||||
export class ImageKnifeDispatcher {
|
||||
// 最大并发
|
||||
|
@ -41,12 +42,12 @@ export class ImageKnifeDispatcher {
|
|||
private jobQueue: IJobQueue = new DefaultJobQueue()
|
||||
// 执行中的请求
|
||||
executingJobMap: LightWeightMap<string, List<ImageKnifeRequestWithSource>> = new LightWeightMap();
|
||||
// 开发者可配置全局缓存
|
||||
private engineKeyImpl: EngineKeyInterface = new EngineKeyFactories();
|
||||
|
||||
private keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
||||
|
||||
showFromMemomry(request: ImageKnifeRequest,imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): boolean {
|
||||
showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): boolean {
|
||||
let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(Tools.generateMemoryKey(imageSrc))
|
||||
.loadFromMemoryCache(this.engineKeyImpl.generateCacheKey(imageSrc, request.ImageKnifeOption.signature))
|
||||
if (memoryCache !== undefined) {
|
||||
// 画主图
|
||||
if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
|
@ -63,22 +64,11 @@ export class ImageKnifeDispatcher {
|
|||
return false
|
||||
}
|
||||
|
||||
// 生成唯一的key
|
||||
generateKey(key: string | PixelMap | Resource): string {
|
||||
let keyCache = typeof key == "string"? key : JSON.stringify(key)
|
||||
let result = this.keyCache.get(keyCache)
|
||||
if(result != undefined) {
|
||||
return result
|
||||
} else {
|
||||
result = SparkMD5.hashBinary(keyCache)
|
||||
this.keyCache.put(keyCache,result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
enqueue(request: ImageKnifeRequest): void {
|
||||
|
||||
//1.内存有的话直接渲染
|
||||
if (this.showFromMemomry(request,request.ImageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC)) {
|
||||
if (this.showFromMemomry(request, request.ImageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -93,7 +83,7 @@ export class ImageKnifeDispatcher {
|
|||
executeJob(request: ImageKnifeRequest): void {
|
||||
// 加载占位符
|
||||
if (request.ImageKnifeOption.placeholderSrc !== undefined) {
|
||||
if (this.showFromMemomry(request,request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) === false) {
|
||||
if (this.showFromMemomry(request, request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER) === false) {
|
||||
this.getAndShowImage(request, request.ImageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)
|
||||
}
|
||||
}
|
||||
|
@ -106,7 +96,7 @@ export class ImageKnifeDispatcher {
|
|||
* 获取和显示图片
|
||||
*/
|
||||
getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource): void {
|
||||
let key: string = Tools.generateKey(imageSrc)
|
||||
let key: string = this.engineKeyImpl.generateCacheKey(imageSrc, currentRequest.ImageKnifeOption.signature)
|
||||
let requestList: List<ImageKnifeRequestWithSource> | undefined = this.executingJobMap.get(key)
|
||||
if (requestList == undefined) {
|
||||
requestList = new List()
|
||||
|
@ -141,7 +131,7 @@ export class ImageKnifeDispatcher {
|
|||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.source === ImageKnifeRequestSource.SRC && currentRequest.ImageKnifeOption.errorholderSrc !== undefined) {
|
||||
|
||||
if (this.showFromMemomry(currentRequest,currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) === false) {
|
||||
if (this.showFromMemomry(currentRequest, currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER) === false) {
|
||||
this.getAndShowImage(currentRequest, currentRequest.ImageKnifeOption.errorholderSrc, ImageKnifeRequestSource.ERROR_HOLDER)
|
||||
}
|
||||
}
|
||||
|
@ -164,21 +154,22 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
|
||||
// 保存内存缓存
|
||||
ImageKnife.getInstance().saveMemoryCache(Tools.generateMemoryKey(imageSrc), ImageKnifeData)
|
||||
ImageKnife.getInstance()
|
||||
.saveMemoryCache(this.engineKeyImpl.generateCacheKey(imageSrc, currentRequest.ImageKnifeOption.signature), ImageKnifeData)
|
||||
|
||||
if (requestList !== undefined) {
|
||||
|
||||
// todo 判断request生命周期,已销毁的不需要再绘制
|
||||
// key相同的request,一起绘制
|
||||
requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => {
|
||||
if (requestWithSource.request.requestState === ImageKnifeRequestState.DESTROY){
|
||||
if (requestWithSource.request.requestState === ImageKnifeRequestState.DESTROY) {
|
||||
return
|
||||
}
|
||||
// 画主图
|
||||
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)
|
||||
requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion, ImageKnifeData.source)
|
||||
}
|
||||
|
||||
if (requestWithSource.source == ImageKnifeRequestSource.SRC) {
|
||||
|
@ -201,15 +192,9 @@ export class ImageKnifeDispatcher {
|
|||
}
|
||||
|
||||
dispatchNextJob() {
|
||||
while (true) {
|
||||
let request = this.jobQueue.pop()
|
||||
if (request === undefined){
|
||||
break// 队列已无任务
|
||||
}
|
||||
else if (request.requestState === ImageKnifeRequestState.PROGRESS) {
|
||||
this.executeJob(request)
|
||||
break
|
||||
}
|
||||
let request = this.jobQueue.pop()
|
||||
if (request !== undefined) {
|
||||
this.executeJob(request)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -218,6 +203,10 @@ export class ImageKnifeDispatcher {
|
|||
this.maxRequests = concurrency
|
||||
}
|
||||
}
|
||||
|
||||
setEngineKeyImpl(impl: EngineKeyInterface): void {
|
||||
this.engineKeyImpl = impl;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -329,7 +318,7 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
|
|||
if (typeValue === 'gif' || typeValue === 'webp') {
|
||||
let base64Help = new util.Base64Helper()
|
||||
|
||||
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf))
|
||||
let base64str = "data:image/" + typeValue + ";base64," + base64Help.encodeToStringSync(new Uint8Array(resBuf))
|
||||
return {
|
||||
pixelMap: base64str,
|
||||
bufferSize: bufferSize
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
*/
|
||||
import taskpool from '@ohos.taskpool';
|
||||
import common from '@ohos.app.ability.common'
|
||||
import { ObjectKey } from './model/ObjectKey';
|
||||
|
||||
@Observed
|
||||
export class ImageKnifeOption {
|
||||
|
@ -24,6 +25,9 @@ export class ImageKnifeOption {
|
|||
// 失败占位图
|
||||
errorholderSrc?: PixelMap | Resource;
|
||||
|
||||
// 自定义缓存关键字
|
||||
signature?: ObjectKey;
|
||||
|
||||
objectFit?: ImageFit
|
||||
|
||||
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>
|
||||
|
|
|
@ -19,7 +19,6 @@ import common from '@ohos.app.ability.common';
|
|||
import { SparkMD5 } from './3rd_party/sparkmd5/spark-md5'
|
||||
import { LogUtil } from './utils/LogUtil'
|
||||
import { ImageKnifeRequestSource } from './ImageKnifeDispatcher';
|
||||
import { Tools } from './utils/Tools';
|
||||
|
||||
|
||||
export class ImageKnifeRequest {
|
||||
|
|
|
@ -20,7 +20,6 @@ import { LogUtil } from '../utils/LogUtil';
|
|||
import componentUtils from '@ohos.arkui.componentUtils'
|
||||
import util from '@ohos.util'
|
||||
import inspector from '@ohos.arkui.inspector'
|
||||
import { Tools } from '../utils/Tools';
|
||||
import { ImageKnifeData } from '../model/ImageKnifeData'
|
||||
|
||||
@Component
|
||||
|
@ -34,7 +33,6 @@ export struct ImageKnifeComponent {
|
|||
private lastHeight: number = 0
|
||||
private currentWidth: number = 0
|
||||
private currentHeight: number = 0
|
||||
private lastSrc: string | PixelMap | Resource = "";
|
||||
private componentVersion: number = 0
|
||||
private currentContext: common.UIAbilityContext | undefined = undefined
|
||||
@State keyCanvas: KeyCanvas = {
|
||||
|
@ -43,16 +41,17 @@ export struct ImageKnifeComponent {
|
|||
private listener: inspector.ComponentObserver = inspector.createComponentObserver(this.keyCanvas.keyId)
|
||||
|
||||
aboutToAppear(): void {
|
||||
let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
.loadFromMemoryCache(Tools.generateMemoryKey(this.ImageKnifeOption.loadSrc))
|
||||
if (memoryCache !== undefined){
|
||||
LogUtil.log("aboutToAppear load from memory cache for key = "+ Tools.generateMemoryKey(this.ImageKnifeOption.loadSrc))
|
||||
//画主图
|
||||
this.pixelMap = memoryCache.source;
|
||||
}else {
|
||||
LogUtil.log("aboutToAppear onLayoutComplete")
|
||||
this.listener.on("layout", this.onLayoutComplete)
|
||||
}
|
||||
//闪动问题失效,注释相应代码后续修复
|
||||
// let memoryCache: ImageKnifeData | undefined = ImageKnife.getInstance()
|
||||
// .loadFromMemoryCache(Tools.generateMemoryKey(this.ImageKnifeOption.loadSrc))
|
||||
// if (memoryCache !== undefined){
|
||||
// LogUtil.log("aboutToAppear load from memory cache for key = "+ Tools.generateMemoryKey(this.ImageKnifeOption.loadSrc))
|
||||
// //画主图
|
||||
// this.pixelMap = memoryCache.source;
|
||||
// }else {
|
||||
LogUtil.log("aboutToAppear onLayoutComplete")
|
||||
this.listener.on("layout", this.onLayoutComplete)
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
@ -79,14 +78,12 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
|
||||
watchImageKnifeOption() {
|
||||
if (this.lastSrc !== this.ImageKnifeOption.loadSrc) {
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
this.request = undefined
|
||||
this.componentVersion++
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
if (this.request !== undefined) {
|
||||
this.request.requestState = ImageKnifeRequestState.DESTROY
|
||||
}
|
||||
this.request = undefined
|
||||
this.componentVersion++
|
||||
ImageKnife.getInstance().execute(this.getRequest(this.currentWidth, this.currentHeight))
|
||||
}
|
||||
getCurrentContext(): common.UIAbilityContext{
|
||||
if(this.currentContext == undefined) {
|
||||
|
@ -96,7 +93,6 @@ export struct ImageKnifeComponent {
|
|||
}
|
||||
getRequest(width: number, height: number): ImageKnifeRequest {
|
||||
if (this.request == undefined) {
|
||||
this.lastSrc = this.ImageKnifeOption.loadSrc
|
||||
this.request = new ImageKnifeRequest(
|
||||
this.ImageKnifeOption,
|
||||
this.ImageKnifeOption.context !== undefined ? this.ImageKnifeOption.context : this.getCurrentContext(),
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import util from '@ohos.util';
|
||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||
import { ObjectKey } from '../model/ObjectKey';
|
||||
import { EngineKeyInterface } from './EngineKeyInterface';
|
||||
|
||||
export class EngineKeyFactories implements EngineKeyInterface {
|
||||
|
||||
private keyCache: util.LRUCache<string,string> = new util.LRUCache(1024)
|
||||
|
||||
// 生成内存缓存
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string {
|
||||
let key = "loadSrc=" + this.generateKey(loadSrc) + ";";
|
||||
if (signature) {
|
||||
key += "signature=" + signature.getKey() + ";"
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
// key缓存策略,避免无意义的 JSON.stringify
|
||||
private generateKey(key: string | PixelMap | Resource): string {
|
||||
let keyCache = typeof key == "string" ? key : JSON.stringify(key)
|
||||
let result = this.keyCache.get(keyCache)
|
||||
if (result != undefined) {
|
||||
return result
|
||||
} else {
|
||||
result = SparkMD5.hashBinary(keyCache)
|
||||
this.keyCache.put(keyCache, result)
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* Copyright (C) 2023 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the 'License');
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an 'AS IS' BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import { ObjectKey } from '../model/ObjectKey'
|
||||
|
||||
export interface EngineKeyInterface {
|
||||
// 生成缓存key
|
||||
generateCacheKey(loadSrc: string | PixelMap | Resource, signature?: ObjectKey | undefined): string
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (C) 2021 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
export class ObjectKey{
|
||||
|
||||
private objectKey: string;
|
||||
|
||||
constructor(objectKey: string) {
|
||||
this.objectKey = objectKey;
|
||||
}
|
||||
|
||||
getKey(): string{
|
||||
return this.objectKey;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -16,6 +16,7 @@ import util from '@ohos.util';
|
|||
import { FileUtils } from './FileUtils';
|
||||
import fs from '@ohos.file.fs';
|
||||
import { LogUtil } from './LogUtil';
|
||||
import { SparkMD5 } from '../3rd_party/sparkmd5/spark-md5';
|
||||
|
||||
|
||||
/**
|
||||
|
@ -172,8 +173,8 @@ export class FileCache {
|
|||
|
||||
let remove: number | undefined = this.lruCache.remove(key)
|
||||
if (remove !== undefined) {
|
||||
FileUtils.getInstance().deleteFile(this.path + key)
|
||||
this.removeMemorySize(remove)
|
||||
FileUtils.getInstance().deleteFile(this.path + key)
|
||||
this.removeMemorySize(remove)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -204,10 +205,10 @@ export class FileCache {
|
|||
break
|
||||
}
|
||||
let delkey = this.lruCache.keys()[0]
|
||||
let remove: number | undefined = this.lruCache.remove(this.lruCache.keys()[0])
|
||||
if (remove !== undefined) {
|
||||
let data: ArrayBuffer | undefined = FileUtils.getInstance().readFileSync(this.path + delkey)
|
||||
if (data !== undefined) {
|
||||
FileUtils.getInstance().deleteFile(this.path + delkey)
|
||||
this.removeMemorySize(remove)
|
||||
this.removeMemorySize(data)
|
||||
}
|
||||
this.lruCache.remove(delkey)
|
||||
}
|
||||
|
@ -242,8 +243,9 @@ export class FileCache {
|
|||
*/
|
||||
static saveFileCacheOnlyFile(context: Context, key: string, value: ArrayBuffer): boolean {
|
||||
// 写文件
|
||||
let md5Key = SparkMD5.hashBinary(key)
|
||||
FileUtils.getInstance()
|
||||
.writeFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key, value)
|
||||
.writeFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + md5Key, value)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -255,7 +257,8 @@ export class FileCache {
|
|||
*/
|
||||
static getFileCacheByFile(context: Context, key: string): ArrayBuffer | undefined {
|
||||
// 从文件获取查看是否有缓存
|
||||
let md5Key = SparkMD5.hashBinary(key)
|
||||
return FileUtils.getInstance()
|
||||
.readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key)
|
||||
.readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + md5Key)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue