Pre Merge pull request !224 from zgf/3.x

This commit is contained in:
zgf 2024-04-27 08:26:14 +00:00 committed by Gitee
commit 4b2df9e6e7
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
9 changed files with 127 additions and 11 deletions

View File

@ -62,7 +62,12 @@ struct Index {
}); });
}) })
Button("测试文件缓存预加载").onClick(()=>{
router.push({
uri: 'pages/TestPrefetchToFileCache',
});
})
} }
.width('100%') .width('100%')

View File

@ -18,20 +18,20 @@ import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife';
@Component @Component
struct ListPage { struct ListPage {
private datas: string[] = [] private data: string[] = []
@State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')} @State ImageKnifeOption: ImageKnifeOption = { loadSrc: $r('app.media.startIcon')}
aboutToAppear(): void { aboutToAppear(): void {
for (let i = 0; i < 1000; i++) { for (let i = 0; i < 1000; i++) {
this.datas.push(i.toString()) this.data.push(i.toString())
} }
} }
build() { build() {
Row() { Row() {
List({ space: 10 }) { List({ space: 10 }) {
ForEach(this.datas, (item: string) => { ForEach(this.data, (item: string) => {
ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200) ImageKnifeComponent({ ImageKnifeOption: this.ImageKnifeOption }).height(200).width(200)
}, (item: string) => item) }, (item: string) => item)
} }

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2024 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,ImageKnife,ImageKnifeOption } from '@ohos/imageknife'
@Entry
@Component
struct TestPrefetchToFileCachePage {
@State imageKnifeOption: ImageKnifeOption = {
loadSrc:$r('app.media.startIcon'),
placeholderSrc:$r('app.media.loading')
}
async preload(url:string) {
let fileCachePath = await ImageKnife.getInstance().prefetchToFileCache(url)
console.log("preload-fileCachePath=="+ fileCachePath)
}
build() {
Column() {
Button("磁盘预加载").onClick(async ()=>{
await this.preload("https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658")
})
Button("加载图片").onClick(()=>{
this.imageKnifeOption.loadSrc = "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658"
})
ImageKnifeComponent({
ImageKnifeOption: this.imageKnifeOption
}).width(300).height(300)
}
.height('100%') .width('100%')
}
}

View File

@ -16,7 +16,7 @@ export struct UserAvatar {
imgSizes: number = 1 imgSizes: number = 1
@State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption() @State ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption()
@StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0 @StorageProp('WeLink_Mob_fontSize_multiple') @Watch('updateImgSize') WeLink_Mob_fontSize_multiple: number = 0
scaleable: boolean = true; scalable: boolean = true;
@State calcImgSize: number = 100 @State calcImgSize: number = 100
aboutToAppear(): void { aboutToAppear(): void {
@ -25,7 +25,7 @@ export struct UserAvatar {
} }
setImageSize() { setImageSize() {
if (!this.scaleable) { if (!this.scalable) {
this.calcImgSize = this.imgSize this.calcImgSize = this.imgSize
} else if (this.WeLink_Mob_fontSize_multiple < 0.9) { } else if (this.WeLink_Mob_fontSize_multiple < 0.9) {
this.calcImgSize = this.imgSize * 0.9 this.calcImgSize = this.imgSize * 0.9

View File

@ -7,6 +7,7 @@
"pages/LongImagePage", "pages/LongImagePage",
"pages/TransformPage", "pages/TransformPage",
"pages/UserPage", "pages/UserPage",
"pages/TestImageFlash" "pages/TestImageFlash",
"pages/TestPrefetchToFileCache"
] ]
} }

View File

@ -18,6 +18,9 @@ import { MemoryLruCache } from './utils/MemoryLruCache';
import { IMemoryCache } from './utils/IMemoryCache' import { IMemoryCache } from './utils/IMemoryCache'
import { FileCache } from './utils/FileCache'; import { FileCache } from './utils/FileCache';
import { ImageKnifeDispatcher } from './ImageKnifeDispatcher'; import { ImageKnifeDispatcher } from './ImageKnifeDispatcher';
import { ImageKnifeOption } from './ImageKnifeOption';
import { Tools } from './utils/Tools';
import { common } from '@kit.AbilityKit';
export class ImageKnife { export class ImageKnife {
@ -84,6 +87,40 @@ export class ImageKnife {
saveFileCache(key: string, data: ArrayBuffer): void { saveFileCache(key: string, data: ArrayBuffer): void {
this.fileCache?.put(key, data) this.fileCache?.put(key, data)
} }
getFileCache(): FileCache{
return this.fileCache as FileCache
}
// 预加载到文件缓存,并返回缓存路径
prefetchToFileCache(url:string): Promise<string> {
return new Promise((resolve,reject)=>{
let imageKnifeOption = new ImageKnifeOption()
imageKnifeOption.loadSrc = url
let keys = Tools.generateKey(url)
let cachePath = ImageKnife.getInstance().getFileCache().getFileToPath(keys)
if(cachePath == null || cachePath == "" || cachePath == undefined) {
let request = new ImageKnifeRequest(
imageKnifeOption,
imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext(this) as common.UIAbilityContext,
0,
0,
0,
{
showPixelMap(version: number, pixelMap: PixelMap | string) {
let cachePaths = ImageKnife.getInstance().getFileCache().getFileToPath(keys)
if(cachePaths != "") {
resolve(cachePaths)
} else {
reject(undefined)
}
}
}
)
this.execute(request)
} else {
resolve(cachePath)
}
})
}
/** /**
* 清除所有文件缓存 * 清除所有文件缓存

View File

@ -121,7 +121,9 @@ export class ImageKnifeDispatcher {
context: currentRequest.context, context: currentRequest.context,
src: imageSrc, src: imageSrc,
key: key, key: key,
customGetImage: currentRequest.ImageKnifeOption.customGetImage customGetImage: currentRequest.ImageKnifeOption.customGetImage,
onlyRetrieveFromCache: currentRequest.ImageKnifeOption.onlyRetrieveFromCache,
requestSource
} }
// 启动线程下载和解码主图 // 启动线程下载和解码主图
let task = new taskpool.Task(requestJob, request) let task = new taskpool.Task(requestJob, request)
@ -164,7 +166,9 @@ export class ImageKnifeDispatcher {
} }
// 保存内存缓存 // 保存内存缓存
if(currentRequest.ImageKnifeOption.isCacheable == undefined || currentRequest.ImageKnifeOption.isCacheable == true) {
ImageKnife.getInstance().saveMemoryCache(Tools.generateMemoryKey(imageSrc), ImageKnifeData) ImageKnife.getInstance().saveMemoryCache(Tools.generateMemoryKey(imageSrc), ImageKnifeData)
}
if (requestList !== undefined) { if (requestList !== undefined) {
@ -250,7 +254,7 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载 if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载
// 先从文件缓存获取 // 先从文件缓存获取
resBuf = FileCache.getFileCacheByFile(request.context, request.key) resBuf = FileCache.getFileCacheByFile(request.context, request.key)
if (resBuf === undefined) { if (resBuf === undefined && request.onlyRetrieveFromCache != true && request.requestSource == 0) {
// // 模拟耗时验证 // // 模拟耗时验证
// let start = (new Date()).getTime(); // let start = (new Date()).getTime();
// while ((new Date()).getTime() - start < 5000) { // while ((new Date()).getTime() - start < 5000) {
@ -309,7 +313,12 @@ async function requestJob(request: RequestJobRequest): Promise<RequestJobResult
} }
} }
} else if ((request.src as Resource).id !== undefined) { //从资源文件获取 } 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 resBuf = request.context.resourceManager.getMediaContentSync((request.src as Resource).id).buffer as ArrayBuffer
} else if (resBuf == undefined && request.requestSource != 0) {
resBuf = request.context.resourceManager.getMediaContentSync((request.src as Resource).id).buffer as ArrayBuffer
}
} }
} }
@ -370,5 +379,7 @@ interface RequestJobRequest {
context: common.UIAbilityContext, context: common.UIAbilityContext,
src: string | PixelMap | Resource, src: string | PixelMap | Resource,
key: string, key: string,
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>,
onlyRetrieveFromCache?: boolean
requestSource:ImageKnifeRequestSource
} }

View File

@ -25,6 +25,10 @@ export class ImageKnifeOption {
errorholderSrc?: PixelMap | Resource; errorholderSrc?: PixelMap | Resource;
objectFit?: ImageFit objectFit?: ImageFit
// 是否开启一级内存缓存
isCacheable?: boolean
// 仅使用缓存加载数据
onlyRetrieveFromCache?: boolean = false;
customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined> customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise<ArrayBuffer | undefined>

View File

@ -258,4 +258,20 @@ export class FileCache {
return FileUtils.getInstance() return FileUtils.getInstance()
.readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key) .readFileSync(context.cacheDir + FileUtils.SEPARATOR + FileCache.CACHE_FOLDER + FileUtils.SEPARATOR + key)
} }
/**
* 获取key缓存数据绝对路径
*
* @params key 数值
*/
getFileToPath(key: string): string {
if(!!!key) {
throw new Error("key is null,checking the parameter")
}
let path = this.path + key
if(FileUtils.getInstance().exist(path)) {
return path
} else {
return ""
}
}
} }