1.新增功能:支持自定义缓存key

2.添加缓存key中的url需要剔除token的演示界面

Signed-off-by: zhoulisheng1 <zhoulisheng1@huawei.com>
This commit is contained in:
zhoulisheng1 2023-03-16 17:39:59 +08:00
parent c6c269fb3e
commit 1b5aea1138
11 changed files with 234 additions and 87 deletions

View File

@ -0,0 +1,63 @@
import { EngineKeyInterface,EngineKeyFactories, RequestOption } from '@ohos/imageknife'
export class CustomEngineKeyImpl implements EngineKeyInterface {
redefineUrl:(loadSrc:string)=>string;
addOtherInfo:string = "Version=1.0.0;"
constructor() {
this.redefineUrl = this.urlNeedClearToken.bind(this);
}
// request只读
generateMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean):string {
return EngineKeyFactories.createMemoryCacheKey(loadSrc,size,transformed,dontAnimate,this.redefineUrl,this.addOtherInfo);
}
generateTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean):string {
return EngineKeyFactories.createTransformedDiskCacheKey(loadSrc,size,transformed,dontAnimate,this.redefineUrl,this.addOtherInfo);
}
generateOriginalDiskCacheKey(loadSrc:string):string {
return EngineKeyFactories.createOriginalDiskCacheKey(loadSrc,this.redefineUrl,this.addOtherInfo);
}
// 需求场景: 请求图片可能 请求中存在token需要清除 可以把输入的url清除token后作为key的一部分这样token发生变化也能命中缓存。
urlNeedClearToken(url:string):string {
if (this.isHttpRequest(url)) {
return this.clearToken(url)
} else {
return url;
}
}
isHttpRequest(loadSrc:string){
if(typeof loadSrc == "string" && loadSrc.toLowerCase().startsWith("http")){
return true;
}
return false;
}
// 清除url里面中携带的token
clearToken(url:string):string{
let retUrl = url.replace(this.findTokenParam(url),"")
return retUrl;
}
// 网络图片加载 可能因为Token问题导致缓存失效
findTokenParam(url: string): string {
let tokenParam = "";
let tokenKeyIndex = url.indexOf("?token=") >= 0 ? url.indexOf("?token=") : url.indexOf("&token=");
if (tokenKeyIndex != -1) {
let nextAndIndex = url.indexOf("&", tokenKeyIndex + 1);
if (nextAndIndex != -1) {
tokenParam = url.substring(tokenKeyIndex + 1, nextAndIndex + 1);
} else {
tokenParam = url.substring(tokenKeyIndex);
}
}
return tokenParam;
}
}

View File

@ -1,7 +1,8 @@
import UIAbility from '@ohos.app.ability.UIAbility';
import hilog from '@ohos.hilog';
import window from '@ohos.window';
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'
import { ImageKnife,ImageKnifeDrawFactory } from '@ohos/imageknife'
import { CustomEngineKeyImpl } from './CustomEngineKeyImpl'
export default class EntryAbility extends UIAbility {
onCreate(want, launchParam) {
@ -9,6 +10,8 @@ export default class EntryAbility extends UIAbility {
globalThis.ImageKnife = ImageKnife.with(this.context);
// 全局配置网络加载进度条
globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
// 全局配置缓存key
globalThis.ImageKnife.setEngineKeyImpl(new CustomEngineKeyImpl())
}
onDestroy() {

View File

@ -12,16 +12,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {ImageKnifeComponent} from '@ohos/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {RotateImageTransformation} from '@ohos/imageknife'
import {RoundedCornersTransformation} from '@ohos/imageknife'
import {
ImageKnifeComponent,
ImageKnifeOption,
RotateImageTransformation,
RoundedCornersTransformation
} from '@ohos/imageknife'
@Entry
@Component
struct FrescoImageTestCasePage {
@State progresshint:string = "输出加载百分比回调信息"
struct CacheRuleChangedPage {
@State progresshint: string = "输出加载百分比回调信息"
@State imageKnifeOption1: ImageKnifeOption =
{
loadSrc: "https://thirdwx.qlogo.cn/mmopen/vi_32/DYAIOgq83ericA1Mv66TwicuYOtbDMBcUhv1aa9RJBeAn9uURfcZD0AUGrJebAn1g2AjN0vb2E1XTET7fTuLBNmA/132",
@ -50,6 +51,14 @@ struct FrescoImageTestCasePage {
{
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
};
@State imageKnifeOption5: ImageKnifeOption =
{
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&baba=sdfsafsafsd",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
@ -58,17 +67,35 @@ struct FrescoImageTestCasePage {
build() {
Scroll() {
Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption })
// ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption3 })
Text('下图默认加载网络图片不带?token=').margin({top:20})
Button('点击加载网络图片?token=').margin({top:5}).onClick(() => {
this.imageKnifeOption4 = {
loadSrc: "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB?token=fsdafsfsafsafsdaf111111",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption4 })
.width(300)
.height(300)
// Scroll() {
// Text(this.progresshint).fontSize(15)
// }.width(300).height(200)
Text('下图默认加载网络图片不带&token=').margin({top:20})
Button('点击加载网络图片&token=').margin({top:5}).onClick(() => {
this.imageKnifeOption5 = {
loadSrc: "https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp?mama=sdafsfasdfsdfsdaf&token=fsdafsfsafsafsdaf111111&baba=sdfsafsafsd",
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
displayProgress: true,
}
})
ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption5 })
.width(300)
.height(300)
}
}
.width('100%')

View File

@ -127,12 +127,12 @@ struct IndexFunctionDemo {
}).margin({ top: 5, left: 3 })
}.width('100%').height(60).backgroundColor(Color.Pink)
Text("测试fresco").fontSize(15)
Text("测试缓存规则和重试").fontSize(15)
Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
Button("加载百分比")
Button("更改缓存规则")
.onClick(() => {
console.log("加载百分比")
router.push({ uri: "pages/frescoImageTestCasePage" });
console.log("更改缓存规则")
router.push({ uri: "pages/CacheRuleChangedPage" });
}).margin({ top: 5, left: 3 })
Button("重试Retry")
.onClick(() => {

View File

@ -1,7 +1,7 @@
{
"src": [
"pages/index",
"pages/frescoImageTestCasePage",
"pages/CacheRuleChangedPage",
"pages/frescoRetryTestCasePage",
"pages/basicTestFeatureAbilityPage",
"pages/basicTestFileIOPage",

View File

@ -27,6 +27,8 @@ export * from './src/main/ets/components/cache/diskstrategy/enum/AUTOMATIC'
export * from './src/main/ets/components/cache/diskstrategy/enum/DATA'
export * from './src/main/ets/components/cache/diskstrategy/enum/NONE'
export * from './src/main/ets/components/cache/diskstrategy/enum/RESOURCE'
export * from './src/main/ets/components/cache/key/EngineKeyInterface'
export * from './src/main/ets/components/cache/key/EngineKeyFactories'
/**
* compress

View File

@ -17,76 +17,50 @@ import {RequestOption} from '../../imageknife/RequestOption'
import {BaseTransform} from '../../imageknife/transform/BaseTransform'
export class EngineKey implements Key {
private request: RequestOption;
constructor(
request
) {
this.request = request;
}
// 内存缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目
// 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图)
generateCacheKey(): string{
public static generateMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean, redefine?:(loadSrc:string)=>string, otherInfo?:string): string{
let loadSrc = JSON.stringify(this.request.loadSrc);
let size = JSON.stringify(this.request.size);
let transformationsStr;
if(this.request && this.request.transformations) {
for (let i = 0; i < this.request.transformations.length; i++) {
if (i == this.request.transformations.length - 1) {
transformationsStr += this.request.transformations[i].getName() + "";
} else {
transformationsStr += this.request.transformations[i].getName() + ",";
}
}
if(redefine){
loadSrc = redefine(loadSrc);
}
let dontAnimateFlag = JSON.stringify(this.request.dontAnimateFlag);
let key = "loadSrc=" + loadSrc + ";" +
"size=" + size + ";" +
"transformations=" + transformationsStr + ";" +
"dontAnimateFlag=" + dontAnimateFlag + ";"
"transformations=" + transformed + ";" +
"dontAnimateFlag=" + dontAnimate + ";"
if(otherInfo){
key += otherInfo;
}
return key;
}
// 磁盘缓存 缓存生成规则:是否会影响图片内容,不影响则通用(strategy onlyRetrieveFromCache isCacheable)为通用项目
// 生成规则 加载数据原 各类参数(排除监听 排除 占位图 失败占位图)
generateResourceKey(): string{
let loadSrc = JSON.stringify(this.request.loadSrc);
let size = JSON.stringify(this.request.size);
let transformationsStr;
if(this.request && this.request.transformations) {
for (let i = 0; i < this.request.transformations.length; i++) {
if (i == this.request.transformations.length - 1) {
transformationsStr += this.request.transformations[i].getName() + "";
} else {
transformationsStr += this.request.transformations[i].getName() + ",";
}
}
public static generateTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean, redefine?:(loadSrc:string)=>string, otherInfo?:string): string{
if(redefine){
loadSrc = redefine(loadSrc);
}
let dontAnimateFlag = JSON.stringify(this.request.dontAnimateFlag);
let key = "loadSrc=" + loadSrc + ";" +
"size=" + size + ";" +
"transformations=" + transformationsStr + ";" +
"dontAnimateFlag=" + dontAnimateFlag + ";"
"transformations=" + transformed + ";" +
"dontAnimateFlag=" + dontAnimate + ";"
if(otherInfo){
key += otherInfo;
}
return key;
}
// 磁盘缓存
// 生成网络加载数据 原始数据存于磁盘的key
generateDataKey(): string{
let loadSrc = JSON.stringify(this.request.loadSrc);
public static generateOriginalDiskCacheKey(loadSrc:string, redefine?:(loadSrc:string)=>string, otherInfo?:string): string{
if(redefine){
loadSrc = redefine(loadSrc);
}
let key = "loadSrc=" + loadSrc + ";"
if(otherInfo){
key += otherInfo;
}
return key;
}

View File

@ -13,24 +13,39 @@
* limitations under the License.
*/
import {EngineKey} from '../key/EngineKey'
import {EngineKeyInterface} from '../key/EngineKeyInterface'
import {RequestOption} from '../../imageknife/RequestOption'
export class EngineKeyFactories {
buildCacheKey(
request) {
return new EngineKey(request).generateCacheKey();
export class EngineKeyFactories implements EngineKeyInterface {
// 生成内存缓存
generateMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean) {
return EngineKey.generateMemoryCacheKey(loadSrc,size,transformed,dontAnimate);
}
// 生成原图变换后的图片的磁盘缓存
generateTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean) {
return EngineKey.generateTransformedDiskCacheKey(loadSrc,size,transformed,dontAnimate);
}
// 生成原图的磁盘缓存
generateOriginalDiskCacheKey(loadSrc:string) {
return EngineKey.generateOriginalDiskCacheKey(loadSrc);
}
buildDataKey(
request
) {
return new EngineKey(request).generateDataKey()
public static createMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string{
return EngineKey.generateMemoryCacheKey(loadSrc,size,transformed,dontAnimate,redefineUrl,addOtherInfo);
}
buildResourceKey(
request
) {
return new EngineKey(request).generateResourceKey()
public static createTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string {
return EngineKey.generateTransformedDiskCacheKey(loadSrc,size,transformed,dontAnimate,redefineUrl,addOtherInfo);
}
public static createOriginalDiskCacheKey(loadSrc:string, redefineUrl?:(loadSrc:string)=>string, addOtherInfo?:string):string {
return EngineKey.generateOriginalDiskCacheKey(loadSrc,redefineUrl,addOtherInfo);
}
}

View File

@ -0,0 +1,27 @@
/*
* 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 {RequestOption} from '../../imageknife/RequestOption'
export interface EngineKeyInterface {
// 生成内存缓存
generateMemoryCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean) : string
// 生成原图变换后的图片的磁盘缓存
generateTransformedDiskCacheKey(loadSrc:string,size:string,transformed:string,dontAnimate:boolean) : string
// 生成原图的磁盘缓存
generateOriginalDiskCacheKey(loadSrc:string) : string
}

View File

@ -16,6 +16,7 @@
import { DiskLruCache } from "@ohos/disklrucache"
import { LruCache } from "../cache/LruCache"
import {EngineKeyFactories} from "../cache/key/EngineKeyFactories"
import {EngineKeyInterface} from "../cache/key/EngineKeyInterface"
import {RequestOption} from "../imageknife/RequestOption"
import {AsyncCallback} from "../imageknife/interface/asynccallback"
import {PlaceHolderManager} from "../imageknife/holder/PlaceHolderManager"
@ -60,7 +61,8 @@ export class ImageKnife {
private defaultLifeCycle: IDrawLifeCycle;
// 开发者可配置全局缓存
private engineKeyImpl: EngineKeyInterface;
private constructor(imgCtx) {
this.imageKnifeContext = imgCtx;
@ -85,6 +87,8 @@ export class ImageKnife {
// 通用文件格式识别初始化
this.fileTypeUtil = new FileTypeUtil();
this.engineKeyImpl = new EngineKeyFactories();
}
getMemoryCache(): LruCache<string, any>{
@ -137,6 +141,9 @@ export class ImageKnife {
this.defaultLifeCycle = viewLifeCycle;
}
setEngineKeyImpl(impl:EngineKeyInterface){
this.engineKeyImpl = impl;
}
private static sInstance: ImageKnife;
@ -217,18 +224,45 @@ export class ImageKnife {
let cacheKey;
let transferKey;
let dataKey;
factories = new EngineKeyFactories();
if(this.engineKeyImpl){
factories = this.engineKeyImpl;
}else {
factories = new EngineKeyFactories();
}
// 生成内存缓存key 内存 变换后磁盘
cacheKey = factories.buildCacheKey(request);
let loadKey = '';
if(typeof request.loadSrc == 'string'){
loadKey = request.loadSrc;
}else{
loadKey = JSON.stringify(request.loadSrc);
}
let size = JSON.stringify(request.size);
let transformed = '';
if(request && request.transformations) {
for (let i = 0; i < request.transformations.length; i++) {
if (i == request.transformations.length - 1) {
transformed += request.transformations[i].getName() + "";
} else {
transformed += request.transformations[i].getName() + ",";
}
}
}
let dontAnimateFlag = request.dontAnimateFlag;
cacheKey = factories.generateMemoryCacheKey(loadKey,size,transformed,dontAnimateFlag);
// 生成磁盘缓存变换后数据key 变换后数据保存在磁盘
transferKey = factories.buildResourceKey(request);
transferKey = factories.generateTransformedDiskCacheKey(loadKey,size,transformed,dontAnimateFlag);
// 生成磁盘缓存源数据key 原始数据保存在磁盘
dataKey = factories.buildDataKey(request);
dataKey = factories.generateOriginalDiskCacheKey(loadKey);
request.generateCacheKey = cacheKey;
request.generateResourceKey = transferKey;

View File

@ -13,8 +13,10 @@
"dependencies": {
"@ohos/hypium": "1.0.3",
"@ohos/hvigor-ohos-plugin": "1.4.0",
"decode-ico": "^0.4.1",
"hypium": "^1.0.0",
"@ohos/hvigor": "1.4.0",
"@ohos/gif-drawable": "^0.2.1",
"@ohos/gpu_transform": "^0.1.0"
}
}