From af980486e9dc7a0a02f59bcccd1bdc6bd99504e1 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 16 Oct 2024 17:31:56 +0800 Subject: [PATCH 1/9] =?UTF-8?q?=E5=8E=BB=E6=8E=89=E5=A4=9A=E4=BD=99?= =?UTF-8?q?=E7=9A=84=E6=97=A5=E5=BF=97=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- library/src/main/ets/ImageKnife.ets | 1 - 1 file changed, 1 deletion(-) diff --git a/library/src/main/ets/ImageKnife.ets b/library/src/main/ets/ImageKnife.ets index e91344a..79c9fe6 100644 --- a/library/src/main/ets/ImageKnife.ets +++ b/library/src/main/ets/ImageKnife.ets @@ -314,7 +314,6 @@ export class ImageKnife { if (cacheType == CacheStrategy.Memory) { return (this.memoryCache as MemoryLruCache).maxMemory; } else { - console.log("sss---->isFileCacheInit:"+this.fileCache) if (this.isFileCacheInit()) { return this.fileCache?.maxMemory; } else { From e7db7e1c752e2a0c5592611d77596d3aa1f2548f Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 16 Oct 2024 18:07:40 +0800 Subject: [PATCH 2/9] =?UTF-8?q?TestCacheDataPage=20=E6=96=87=E4=BB=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=89=88=E6=9D=83=E5=A4=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- entry/src/main/ets/pages/TestCacheDataPage.ets | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/entry/src/main/ets/pages/TestCacheDataPage.ets b/entry/src/main/ets/pages/TestCacheDataPage.ets index 3cdb530..4428de7 100644 --- a/entry/src/main/ets/pages/TestCacheDataPage.ets +++ b/entry/src/main/ets/pages/TestCacheDataPage.ets @@ -1,3 +1,18 @@ +/* + * 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 { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife'; @Entry From d257d95e7b4283229dbd01027394a3e0c3c0c598 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 17 Oct 2024 14:32:40 +0800 Subject: [PATCH 3/9] =?UTF-8?q?=E8=B5=84=E6=BA=90=E5=9B=BD=E9=99=85?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- entry/src/main/ets/pages/Index.ets | 68 +++++----- entry/src/main/ets/pages/LoadStatePage.ets | 6 +- .../src/main/ets/pages/TestCacheDataPage.ets | 60 ++++----- .../main/ets/pages/TestChangeColorPage.ets | 26 ++-- .../ets/pages/TestLoadCancelListenerPage.ets | 15 ++- .../main/resources/base/element/string.json | 120 ++++++++++++++++++ .../base/media/ic_test_change_color_png.png | Bin 0 -> 3440 bytes .../base/media/ic_test_change_color_svg.svg | 14 ++ entry/src/main/resources/base/media/test.png | Bin 9714 -> 0 bytes .../main/resources/base/media/test_svg.svg | 9 -- .../main/resources/zh_CN/element/string.json | 120 +++++++++++++++++- 11 files changed, 339 insertions(+), 99 deletions(-) create mode 100644 entry/src/main/resources/base/media/ic_test_change_color_png.png create mode 100644 entry/src/main/resources/base/media/ic_test_change_color_svg.svg delete mode 100644 entry/src/main/resources/base/media/test.png delete mode 100644 entry/src/main/resources/base/media/test_svg.svg diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 697f387..45db76e 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -17,125 +17,125 @@ import router from '@system.router'; @Entry @ComponentV2 struct Index { - - getResourceString(res:Resource){ + getResourceString(res: Resource) { return getContext().resourceManager.getStringSync(res.id) } - aboutToAppear(): void { } build() { - Scroll(){ + Scroll() { Column() { - Button($r('app.string.Test_ImageAnimator')).onClick(()=>{ + Button($r('app.string.Test_ImageAnimator')).onClick(() => { router.push({ uri: 'pages/ImageAnimatorPage', }); }) - Button($r('app.string.Test_multiple_images')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_multiple_images')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestCommonImage', }); }) - Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach").margin({top:10}).onClick(()=>{ - router.push({ - uri: 'pages/UserPage', + Button(this.getResourceString($r('app.string.Multiple_images')) + " + reuse + LazyForeach") + .margin({ top: 10 }) + .onClick(() => { + router.push({ + uri: 'pages/UserPage', - }); - }) - Button($r('app.string.Test_SingleImage')).margin({top:10}).onClick(()=>{ + }); + }) + Button($r('app.string.Test_SingleImage')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/SingleImage', }); }) - Button($r('app.string.Display_long_image')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Display_long_image')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/LongImagePage', }); }) - Button($r('app.string.Image_Transformation')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Image_Transformation')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/ImageTransformation', }); }) - Button($r('app.string.Test_media_URL')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_media_URL')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/dataShareUriLoadPage', }); }) - Button($r('app.string.Different_ObjectFit')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Different_ObjectFit')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/ObjectFitPage', }); }) - Button($r('app.string.Custom_cache_key')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Custom_cache_key')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/SignatureTestPage', }); }) - Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_image_loading_success_or_failure_events')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/LoadStatePage', }) }) - Button($r('app.string.Image_scaling')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Image_scaling')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TransformPage', }); }) - Button($r('app.string.Test_HSP')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_HSP')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestHspPreLoadImage', }); }) - Button($r('app.string.Test_custom_download')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_custom_download')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestSetCustomImagePage', }); }) - Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({top:10}).onClick(()=>{ + Button(this.getResourceString($r('app.string.Message_list')) + " + List").margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestImageFlash', }); }) - Button($r('app.string.Preloading_images_to_cache')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Preloading_images_to_cache')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestPrefetchToFileCache', }); }) - Button($r('app.string.Retrieve_image_display_from_cache')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Retrieve_image_display_from_cache')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestIsUrlExist', }); }) - Button($r('app.string.Test_single_request_header')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_single_request_header')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestHeader', }); }) - Button($r('app.string.Test_write_cache_strategy')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_write_cache_strategy')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestWriteCacheStage', @@ -143,41 +143,39 @@ struct Index { }) - Button($r('app.string.Test_removing_image_cache_interface')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_removing_image_cache_interface')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestRemoveCache', }); }) - Button($r('app.string.Test_error_image_display')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_error_image_display')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestErrorHolderPage', }); }) - Button($r('app.string.Test_Task_error')).margin({top:10}).onClick(()=>{ + Button($r('app.string.Test_Task_error')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestTaskResourcePage', }); }) - Button("测试缓存数据").margin({top:10}).onClick(()=>{ + Button($r('app.string.test_cache_btn')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestCacheDataPage', }); }) - Button("测试颜色变换").margin({top:10}).onClick(()=>{ + Button($r('app.string.test_change_color_btn')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestChangeColorPage', - }); }) - Button("测试加载取消回调接口").margin({top:10}).onClick(()=>{ + Button($r('app.string.test_cancel_callback_btn')).margin({ top: 10 }).onClick(() => { router.push({ uri: 'pages/TestLoadCancelListenerPage', - }); }) } - } .width('100%') + }.width('100%') .height('100%') } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/LoadStatePage.ets b/entry/src/main/ets/pages/LoadStatePage.ets index a697c75..876a74e 100644 --- a/entry/src/main/ets/pages/LoadStatePage.ets +++ b/entry/src/main/ets/pages/LoadStatePage.ets @@ -79,9 +79,9 @@ struct LoadStatePage { }) } .margin({ top: 20 }) - Text("格式:"+this.typeValue) - Text("宽度:"+this.currentWidth) - Text("高度:"+this.currentHeight) + Text($r('app.string.image_format',this.typeValue)) + Text($r('app.string.image_width',this.currentWidth)) + Text($r('app.string.image_height',this.currentHeight)) ImageKnifeComponent({ imageKnifeOption: this.ImageKnifeOption }).height(this.currentHeight).width(this.currentWidth) .margin({ top: 20 }) Button($r('app.string.Custom_download_failed')).onClick(()=>{ diff --git a/entry/src/main/ets/pages/TestCacheDataPage.ets b/entry/src/main/ets/pages/TestCacheDataPage.ets index 4428de7..44210ab 100644 --- a/entry/src/main/ets/pages/TestCacheDataPage.ets +++ b/entry/src/main/ets/pages/TestCacheDataPage.ets @@ -18,9 +18,9 @@ import { ImageKnife, CacheStrategy, ImageKnifeComponent, ImageKnifeOption } from @Entry @ComponentV2 struct TestCacheDataPage { - @Local cacheUpLimit: string = '当前缓存上限: 0M'; - @Local currentNum: string = '当前缓存图片数量: 0'; - @Local currentSize: string = '当前缓存的大小: 0M'; + @Local cacheUpLimit: number = 0; + @Local currentNum: number = 0; + @Local currentSize: number = 0; @Local currentWidth: number = 200 @Local currentHeight: number = 200 @Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ @@ -38,7 +38,7 @@ struct TestCacheDataPage { }) aboutToAppear(): void { - ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024,"ImageKnifeCache1") + ImageKnife.getInstance().initFileCache(getContext(this), 256, 256 * 1024 * 1024, "ImageKnifeCache1") } build() { @@ -50,66 +50,66 @@ struct TestCacheDataPage { .width(this.currentWidth) .margin({ top: 10 }) - Button('内存加载图片') + Button($r('app.string.load_memory')) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ loadSrc: "https://img0.baidu.com/it/u=1530797181,174436037&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800", objectFit: ImageFit.Contain, - writeCacheStrategy:CacheStrategy.Memory, + writeCacheStrategy: CacheStrategy.Memory, border: { radius: 50 }, }) }) - Button('磁盘缓存加载图片') + Button($r('app.string.load_disk')) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ loadSrc: "https://q7.itc.cn/images01/20240223/ce80229bf9934dff97cdf2ad7be1dcb8.jpeg", objectFit: ImageFit.Contain, - writeCacheStrategy:CacheStrategy.File, + writeCacheStrategy: CacheStrategy.File, border: { radius: 50 }, }) }) - Text(this.cacheUpLimit).fontSize(20).margin({bottom:8}); - Text(this.currentNum).fontSize(20).margin({bottom:8}); - Text(this.currentSize).fontSize(20).margin({bottom:20}); + Text($r('app.string.cur_cache_limit', this.cacheUpLimit)).fontSize(20).margin({ bottom: 8 }); + Text($r('app.string.cur_cache_image_num', this.currentNum)).fontSize(20).margin({ bottom: 8 }); + Text($r('app.string.cur_cache_size', this.currentSize)).fontSize(20).margin({ bottom: 20 }); - Button("获取当前内存缓存上限").onClick(() => { + Button($r('app.string.get_cur_memory_limit')).onClick(() => { let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.Memory); if (result) { - this.cacheUpLimit = "当前缓存上限:" + (result/(1024*1024))+"M"; + this.cacheUpLimit = result / (1024 * 1024); } - }).margin({bottom:8}); - Button("获取当前内存缓存图片数量").onClick(() => { + }).margin({ bottom: 8 }); + Button($r('app.string.get_img_number_of_cache')).onClick(() => { let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.Memory); if (result) { - this.currentNum = "当前缓存图片数量:" + result; + this.currentNum = result; } - }).margin({bottom:8}); - Button("获取当前缓存的大小").onClick(() => { + }).margin({ bottom: 8 }); + Button($r('app.string.get_cur_memory_size')).onClick(() => { let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.Memory); if (result) { - this.currentSize = "当前缓存的大小:" + (result/(1024*1024))+"M"; + this.currentSize = result / (1024 * 1024); } - }).margin({bottom:8}); + }).margin({ bottom: 8 }); - Button("获取当前磁盘缓存上限").onClick(() => { + Button($r('app.string.get_cur_disk_limit')).onClick(() => { let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.File); if (result) { - this.cacheUpLimit = "当前缓存上限:" + (result/(1024*1024))+"M"; + this.cacheUpLimit = result / (1024 * 1024); } - }).margin({bottom:8}); - Button("获取当前磁盘缓存图片数量").onClick(() => { + }).margin({ bottom: 8 }); + Button($r('app.string.get_img_number_of_disk')).onClick(() => { let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.File); if (result) { - this.currentNum = "当前缓存图片数量:" + result; + this.currentNum = result; } - }).margin({bottom:8}); - Button("获取当前磁盘的大小").onClick(() => { + }).margin({ bottom: 8 }); + Button($r('app.string.get_cur_disk_size')).onClick(() => { let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.File); if (result) { - this.currentSize = "当前缓存的大小:" + (result/(1024*1024))+"M"; + this.currentSize = result / (1024 * 1024); } - }).margin({bottom:8}); + }).margin({ bottom: 8 }); } - .height('100%').width('100%').margin({top:50}) + .height('100%').width('100%').margin({ top: 50 }) } } \ No newline at end of file diff --git a/entry/src/main/ets/pages/TestChangeColorPage.ets b/entry/src/main/ets/pages/TestChangeColorPage.ets index 665386d..2a282ae 100644 --- a/entry/src/main/ets/pages/TestChangeColorPage.ets +++ b/entry/src/main/ets/pages/TestChangeColorPage.ets @@ -19,8 +19,8 @@ import { ImageKnifeComponent, ImageKnifeOption } from '@ohos/imageknife'; @Entry @Component struct TestChangeColorPage { - private imageOne: Resource = $r('app.media.test'); - private imageTwo: Resource = $r('app.media.test'); + private imageOne: Resource = $r('app.media.ic_test_change_color_png'); + private imageTwo: Resource = $r('app.media.ic_test_change_color_png'); @State src: Resource = this.imageOne @State src2: Resource = this.imageTwo @State color: common2D.Color = { @@ -33,9 +33,9 @@ struct TestChangeColorPage { build() { Column() { - Text("点击选择要更改的颜色").margin({ top: 20 }) + Text($r('app.string.select_color_btn')).margin({ top: 20 }) Row() { - Button("红色").backgroundColor(Color.Red).margin(5).onClick(() => { + Button($r('app.string.red')).backgroundColor(Color.Red).margin(5).onClick(() => { this.color = { alpha: 255, red: 255, @@ -43,7 +43,7 @@ struct TestChangeColorPage { blue: 1 }; }) - Button("黄色").backgroundColor(Color.Yellow).margin(5).onClick(() => { + Button($r('app.string.yellow')).backgroundColor(Color.Yellow).margin(5).onClick(() => { this.color = { alpha: 255, red: 255, @@ -51,7 +51,7 @@ struct TestChangeColorPage { blue: 1 }; }) - Button("绿色").backgroundColor(Color.Green).margin(5).onClick(() => { + Button($r('app.string.green')).backgroundColor(Color.Green).margin(5).onClick(() => { this.color = { alpha: 255, red: 1, @@ -59,7 +59,7 @@ struct TestChangeColorPage { blue: 1 }; }) - Button("蓝色").backgroundColor(Color.Blue).margin(5).onClick(() => { + Button($r('app.string.blue')).backgroundColor(Color.Blue).margin(5).onClick(() => { this.color = { alpha: 255, red: 1, @@ -72,14 +72,14 @@ struct TestChangeColorPage { .height(50) .justifyContent(FlexAlign.Center) - Text("原图:").margin({ top: 20 }) + Text($r('app.string.master_image')).margin({ top: 20 }) ImageKnifeComponent({ imageKnifeOption: new ImageKnifeOption({ loadSrc: this.src }) }).width(110).height(110) - Text("点击图片更改图片颜色:").margin({ top: 30 }) + Text($r('app.string.click_img_to_change_color')).margin({ top: 30 }) ImageKnifeComponent({ imageKnifeOption: new ImageKnifeOption({ loadSrc: this.src, @@ -91,18 +91,18 @@ struct TestChangeColorPage { drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN); }).width(110).height(110) - Text("测试非svg图片变色").margin({ top: 30 }) + Text($r('app.string.test_non_svg_color')).margin({ top: 30 }) ImageKnifeComponent({ imageKnifeOption: new ImageKnifeOption({ - loadSrc: $r('app.media.test'), + loadSrc: $r('app.media.ic_test_change_color_png'), drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN) }) }).width(110).height(110) - Text("测试svg图片变色").margin({ top: 30 }) + Text($r('app.string.test_svg_color')).margin({ top: 30 }) ImageKnifeComponent({ imageKnifeOption: new ImageKnifeOption({ - loadSrc: $r("app.media.test_svg"), + loadSrc: $r("app.media.ic_test_change_color_svg"), drawingColorFilter: drawing.ColorFilter.createBlendModeColorFilter(this.color, drawing.BlendMode.SRC_IN) }) }).width(110).height(110) diff --git a/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets b/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets index d6d1685..9e88f92 100644 --- a/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets +++ b/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets @@ -21,7 +21,7 @@ struct TestLoadCancelListenerPage { @Local currentWidth: number = 200 @Local currentHeight: number = 200 @Local showChild: boolean = true; - @Local text: string = "onLoadCancel回调原因:"; + @Local text: string = ""; @Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ loadSrc: "", objectFit: ImageFit.Contain, @@ -30,8 +30,8 @@ struct TestLoadCancelListenerPage { build() { Column() { - Text(this.text).margin(20).fontSize(15) - Button('移除组件-网络加载图片') + Text($r('app.string.onLoadCancel_reason', this.text)).margin(20).fontSize(15) + Button($r('app.string.rm_component_of_net')) .margin(20) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ @@ -42,7 +42,7 @@ struct TestLoadCancelListenerPage { this.showChild = false; }, onLoadCancel: (res) => { - this.text = "onLoadCancel回调成功,网络nLoadCancel回调原因:" + res + this.text = res console.log("TestLoadCancelListenerPage----onLoadCancel> url:" + res) } }, @@ -50,8 +50,9 @@ struct TestLoadCancelListenerPage { }) }) - Button('恢复组件显示') + Button($r('app.string.component_display')) .margin(20).onClick(() => { + this.text = ""; this.showChild = true; this.ImageKnifeOption = new ImageKnifeOption({ loadSrc: "", @@ -59,7 +60,7 @@ struct TestLoadCancelListenerPage { border: { radius: 50 } }) }) - Button('移除组件-本地资源图片') + Button($r('app.string.rm_component_of_local')) .margin(20) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ @@ -70,7 +71,7 @@ struct TestLoadCancelListenerPage { this.showChild = false; }, onLoadCancel: (res) => { - this.text = "onLoadCancel回调成功,本地onLoadCancel回调原因:" + res + this.text = res console.log("TestLoadCancelListenerPage----onLoadCancel> url:" + res) } }, diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index f982e81..d059311 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -367,6 +367,126 @@ { "name": "TIPS", "value": "Please shut down the network first and ensure that there is no cache of images from this network in the test failure scenario locally" + }, + { + "name": "image_format", + "value": "picture format:%s" + }, + { + "name": "image_width", + "value": "image width:%d" + }, + { + "name": "image_height", + "value": "image height:%d" + }, + { + "name": "cur_cache_limit", + "value": "current cache limit:%dM" + }, + { + "name": "cur_cache_image_num", + "value": "current cache image number:%d" + }, + { + "name": "cur_cache_size", + "value": "current cache size:%dM" + }, + { + "name": "load_memory", + "value": "memory loaded picture" + }, + { + "name": "load_disk", + "value": "disk cache loads images" + }, + { + "name": "get_cur_memory_limit", + "value": "gets the current memory cache upper limit" + }, + { + "name": "get_img_number_of_cache", + "value": "gets the number of images cached in memory" + }, + { + "name": "get_cur_memory_size", + "value": "gets the size of the current cache" + }, + { + "name": "get_cur_disk_limit", + "value": "Gets the current disk cache upper limit" + }, + { + "name": "get_img_number_of_disk", + "value": "gets the number of images cached on disk" + }, + { + "name": "get_cur_disk_size", + "value": "gets the size of the current disk" + }, + { + "name": "select_color_btn", + "value": "click to select the color you want to change" + }, + { + "name": "click_img_to_change_color", + "value": "click on the image to change the image color" + }, + { + "name": "test_non_svg_color", + "value": "test non-SVG images for color change" + }, + { + "name": "test_svg_color", + "value": "Test svg picture color change" + }, + { + "name": "red", + "value": "red" + }, + { + "name": "yellow", + "value": "yellow" + }, + { + "name": "green", + "value": "green" + }, + { + "name": "blue", + "value": "blue" + }, + { + "name": "master_image", + "value": "master image:" + }, + { + "name": "rm_component_of_net", + "value": "remove Component - Network load picture" + }, + { + "name": "rm_component_of_local", + "value": "remove Component - Local resource picture" + }, + { + "name": "component_display", + "value": "recovery component display" + }, + { + "name": "onLoadCancel_reason", + "value": "onLoadCancel callback reason:%s" + }, + { + "name": "test_cache_btn", + "value": "test data for in cache" + }, + { + "name": "test_change_color_btn", + "value": "test change color for image" + }, + { + "name": "test_cancel_callback_btn", + "value": "test callback of cancel" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/media/ic_test_change_color_png.png b/entry/src/main/resources/base/media/ic_test_change_color_png.png new file mode 100644 index 0000000000000000000000000000000000000000..75f0a56c3999613f19b0e1fe30b73236835f0f35 GIT binary patch literal 3440 zcmZu!c|6mP|9@|@G3E-*P35Mj9CK|FMzL5!2Tl4Eqz9syXL6A`serk=ljR=^?bdauh$>1KVFZ=>+wu?#9@U6Wd#8M5Vo_m!te2g zzYu`!#o7EA)Eudup!&hCa3XO*O+9J7tmiG2Dgf#RC^ zv$lmvKEyyt#Ms^8LC5zfP5(_Tk?3BLGSB5G8+h2?F~iK&kG zpIuG=R)>{5?_u8kd4yuH9`|!=c!pL!B3qdNWq>gaRl*+F3N^8z6ryYTm-YO5F(JLNQEMLWJ<+ zKX%|pDl13fn04aq4;?8!evIZb?iN*+ ze5o!F*jUeZNaOARJ;VrPmJhmDoTCP7)ec4yGmhBy+q2Kr>2(f#sG;tpW4*JqXnjx% zIg9VxXDk~;V?nk$r4qf!;^o!YKi4uR&(?QWpx_xm6J%o_^Ornth+SmqZ9%4hx}4(S z;lardPR+u1$5o=Ra^@gNBObBnxq<{O3nVHkL)PcUlq}{~AEPm;Ga46a=z2gxQmGIv4yOZ& zC_$F7I^)~lEzo!Mv)4bq;AJ@l`VRm5z&xz_=PiwtphHODN3KhZ#os0X03c;NT{FrjZ|R}Qob>!G0>AA+ye>`wE? zwCX~Jw`Z-;of9>{s4XEM!Vg|_HV*{MZ^ib>s2_f5O-;h1V@MyADKZC;e2qOHVk8r?|Tv6;-6#QlDhx&}%RKQ;OQ z4(#mLGIg9WD#OdI7zs@Hj2VH1FRThXZS_ne;ScZ9dhFO2(T6zPJAGuvD@ShD(VoaJY_>Ge=_;8?}ieW` zN;(0TGWOmqGwxE`#6F*U>XEDdp7y986>B;bii3QJy3A$=h=}0BGOT6kq*(zH3vnsW zW#L!tPllYIc-ftn)$mB{lknVDSxP}#rA(+0|F_f}uj#4%CK;ii2x0aVeF@Y|VHq<} zEj=C~Io3rK3YzUz+Q7M?9N;DxUILvAzcwtwS(ZgzY2i0Yjc&gP1BYtkXr@DV(hNsx)&ROQ`$r_fLk!iDg_C-Itq(M?KOQ`eSD1184w2%H? zo=%bdN`9&<*zV27=tkAs>DtUKDuyvHY;7}qH#G^qm*{zcf{Pwi?{!yR)M853&;}%z zC&!w&$U~lvTZY6}Mc%UM)_|)X|G7*v4J~g(Q&X?ohFbQroFJ|C%ID3i-;)sNI?3(~?M7jy=?t3-{Q_${Vx3~u;r2EF( zkrtdMRN@kuWoO#E%S29<56en zrzdgwO0=GK3~TAQmfk!s}=E3CD zteu@RrOI62=Wu0d{Dg9p`l@o*H$4TY0P8YIaOYi7HEUA(3~^=)9y?v6V%` zf510=x2PF!bb-EHh70|agG)(lSDlO4XTjBzQ@d8ra!B`U4_ljaQQEPkzutY^#9`L( zXC3T;&$EeR`-U_>8g?A+k;3n;ee|c(TU|W0bCYsSm=e#hu|i!*jOPzYNlNBJ$M)yA)$p*s|~B3i`Ui{pX1=OC#tmhSZH+XSUvJINaa* zR3SSCg+1HrGUJ$dXy4bhidkcZB?1H6u0Lv6eO*d1G$x%`+t|o3@}GBS3dN~gFjG@$ zSr4pgc%IDM-YpK((F>yT3C#ogPRvUnuOi(4Kfn=}`-5%j^Dz+4}w`YHO+uUUf(7At;b= z@~_Z~X9}8UjkZ4`iu$H6f#ZJqwBnp79x44V*UDA?xIk~dZE~yaKWOfu&Z&IZ9h1&_ zwOM9L+*r8miqrRVB;y1o zbrGgF1JE_vYo1Z5rUUo*b^2S6=04Qjuy(L8LS507*Dn0CXg8Tb_Twqs?};eBTrmm} zo>GxblGp{8o{jR>AW(*_wB1aJL36oupP_ZfX6?c$5^qH3bSxbMuB*R~y>*!!tq9|F zM4Wzm6Y)#Hs4aqztHfrNnOp`3KGzFAw`qo8^%dplRnf|+b=BLNtng!sNOBm(47;1THF0sOF7%)#A= z%*El>pSREB>k^F@^^Y!IMRpm+u8XSI`Ek!*at4g>dshUx?`IC9j2aW&&5Ie$j2JIH(;lI#&xynZ!k z$z{}@QSDp^4)erhUcH9dnDY(MF+hqQw;`2|L$fkMOGV~<{i8@zctAb4NM}?-#;BK(NBpm4lnengN_5lr&@$q z-V_vpl$zpCqV+y0Eh_6*JJTLt`kH^5bbt`M?k23qw3$CF_KV1LvgQ^fufPMcjQj5W zP!4O5grh_@_NS-PdTH2EI^=z?+L`fA+-+E zLUxqc5FD9n*YQ*5{`u=m0}R}WcBn5?Q?z}P8OLHtJ^M@k8$*t&D1F;i#avw`rV9f$ypsFn~@z5~ZzNRK6p_cex zBwy;d+Xy5*BIzAp__Z2H8hChSLMB0i*g$*a7TP-9qy~E@EzIvFu?;ry2cL^GWfz#2 zh^B3TI=*kIpLFF)iV`M+ZLY)C{5U*M?SE2nfI(NpwLF&`W?lV#$ z%Iq_*^P)iSue|<%&l8W)-ZtqRn7Y&J38Axg;}~kOPAkLJyDYhGqJyhX$MHFxQf=h+ z#V7)Ep_-f(6cjMle6FED%sT=8T9#KqZ-ZSQ83k{_e2Dd8`<=K$*pVL#|Dq_R~nlw9+{S8<*?>P5wOtfb7{ + + svg细图标 + + + + + + + + + + + \ No newline at end of file diff --git a/entry/src/main/resources/base/media/test.png b/entry/src/main/resources/base/media/test.png deleted file mode 100644 index b0d65d0fa431513655312e60e316a49675bdba52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9714 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 diff --git a/entry/src/main/resources/base/media/test_svg.svg b/entry/src/main/resources/base/media/test_svg.svg deleted file mode 100644 index 9910b1d..0000000 --- a/entry/src/main/resources/base/media/test_svg.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 74fedfe..9f97170 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -361,8 +361,124 @@ "value": "遮罩效果" }, { - "name": "TIPS", - "value": "测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存" + "name": "image_format", + "value": "图片格式:%s" + }, + { + "name": "image_width", + "value": "图片宽度:%d" + }, + { + "name": "image_height", + "value": "图片高度:%d" + }, + { + "name": "cur_cache_limit", + "value": "当前缓存上限:%dM" + }, + { + "name": "cur_cache_image_num", + "value": "当前缓存图片数量:%d" + }, + { + "name": "cur_cache_size", + "value": "当前缓存的大小:%dM" + }, + { + "name": "load_memory", + "value": "内存加载图片" + }, + { + "name": "load_disk", + "value": "磁盘缓存加载图片" + }, + { + "name": "get_cur_memory_limit", + "value": "获取当前内存缓存上限" + }, + { + "name": "get_img_number_of_cache", + "value": "获取当前内存缓存图片数量" + }, + { + "name": "get_cur_memory_size", + "value": "获取当前缓存的大小" + }, + { + "name": "get_cur_disk_limit", + "value": "获取当前磁盘缓存上限" + }, + { + "name": "get_img_number_of_disk", + "value": "获取当前磁盘缓存图片数量" + }, + { + "name": "get_cur_disk_size", + "value": "获取当前磁盘的大小" + }, + { + "name": "select_color_btn", + "value": "点击选择要更改的颜色" + }, + { + "name": "click_img_to_change_color", + "value": "点击图片更改图片颜色" + }, + { + "name": "test_non_svg_color", + "value": "测试非svg图片变色" + }, + { + "name": "test_svg_color", + "value": "测试svg图片变色" + }, + { + "name": "red", + "value": "红色" + }, + { + "name": "yellow", + "value": "黄色" + }, + { + "name": "green", + "value": "绿色" + }, + { + "name": "blue", + "value": "蓝色" + }, + { + "name": "master_image", + "value": "原图:" + }, + { + "name": "rm_component_of_net", + "value": "移除组件-网络加载图片" + }, + { + "name": "rm_component_of_local", + "value": "移除组件-本地资源图片" + }, + { + "name": "component_display", + "value": "恢复组件显示" + }, + { + "name": "onLoadCancel_reason", + "value": "onLoadCancel回调原因:%s" + }, + { + "name": "test_cache_btn", + "value": "测试缓存数据" + }, + { + "name": "test_change_color_btn", + "value": "测试颜色变换" + }, + { + "name": "test_cancel_callback_btn", + "value": "测试加载取消回调接口" } ] } \ No newline at end of file From 4b1e84f5ec6fd0de1257177d0a9cfefa9909fc91 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 17 Oct 2024 14:42:36 +0800 Subject: [PATCH 4/9] add TIPS text dec Signed-off-by: tyBrave --- entry/src/main/resources/zh_CN/element/string.json | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 9f97170..2fed51a 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -360,6 +360,10 @@ "name": "Mask_effect", "value": "遮罩效果" }, + { + "name": "TIPS", + "value": "测试失败场景请先关闭网络,并保证本地没有此网络图片的缓存" + }, { "name": "image_format", "value": "图片格式:%s" From c05e338ceb7d6e98d25e9f30a7136a2f9704887f Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 17 Oct 2024 16:48:54 +0800 Subject: [PATCH 5/9] update code because of checkcode Signed-off-by: tyBrave --- .../src/main/ets/pages/TestCacheDataPage.ets | 35 ++++++++++++++++--- .../main/resources/base/element/string.json | 14 ++++++-- .../main/resources/zh_CN/element/string.json | 14 ++++++-- .../ets/test/imageFormatAndSize.test.ets | 25 +++++++++---- 4 files changed, 70 insertions(+), 18 deletions(-) diff --git a/entry/src/main/ets/pages/TestCacheDataPage.ets b/entry/src/main/ets/pages/TestCacheDataPage.ets index 44210ab..e8da530 100644 --- a/entry/src/main/ets/pages/TestCacheDataPage.ets +++ b/entry/src/main/ets/pages/TestCacheDataPage.ets @@ -23,6 +23,9 @@ struct TestCacheDataPage { @Local currentSize: number = 0; @Local currentWidth: number = 200 @Local currentHeight: number = 200 + @Local markersLimitText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory')) + @Local markersNumText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory')) + @Local markersSizeText: string = getContext(this).resourceManager.getStringSync($r('app.string.memory')) @Local ImageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ loadSrc: "", objectFit: ImageFit.Contain, @@ -53,7 +56,7 @@ struct TestCacheDataPage { Button($r('app.string.load_memory')) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ - loadSrc: "https://img0.baidu.com/it/u=1530797181,174436037&fm=253&fmt=auto&app=120&f=JPEG?w=1422&h=800", + loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg", objectFit: ImageFit.Contain, writeCacheStrategy: CacheStrategy.Memory, border: { radius: 50 }, @@ -62,51 +65,73 @@ struct TestCacheDataPage { Button($r('app.string.load_disk')) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ - loadSrc: "https://q7.itc.cn/images01/20240223/ce80229bf9934dff97cdf2ad7be1dcb8.jpeg", + loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg", objectFit: ImageFit.Contain, writeCacheStrategy: CacheStrategy.File, border: { radius: 50 }, }) }) - Text($r('app.string.cur_cache_limit', this.cacheUpLimit)).fontSize(20).margin({ bottom: 8 }); - Text($r('app.string.cur_cache_image_num', this.currentNum)).fontSize(20).margin({ bottom: 8 }); - Text($r('app.string.cur_cache_size', this.currentSize)).fontSize(20).margin({ bottom: 20 }); + Text($r('app.string.cur_cache_limit', this.markersLimitText, this.cacheUpLimit)) + .fontSize(20) + .margin({ bottom: 8 }); + Text($r('app.string.cur_cache_image_num', this.markersNumText, this.currentNum)) + .fontSize(20) + .margin({ bottom: 8 }); + Text($r('app.string.cur_cache_size', this.markersSizeText, this.currentSize)).fontSize(20).margin({ bottom: 20 }); Button($r('app.string.get_cur_memory_limit')).onClick(() => { let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.Memory); + this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.memory')) if (result) { this.cacheUpLimit = result / (1024 * 1024); + } else { + this.cacheUpLimit = 0; } }).margin({ bottom: 8 }); Button($r('app.string.get_img_number_of_cache')).onClick(() => { let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.Memory); + this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.memory')) if (result) { this.currentNum = result; + } else { + this.currentNum = 0; } }).margin({ bottom: 8 }); Button($r('app.string.get_cur_memory_size')).onClick(() => { let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.Memory); + this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.memory')) if (result) { this.currentSize = result / (1024 * 1024); + } else { + this.currentSize = 0; } }).margin({ bottom: 8 }); Button($r('app.string.get_cur_disk_limit')).onClick(() => { let result = ImageKnife.getInstance().getCacheUpperLimit(CacheStrategy.File); + this.markersLimitText = getContext(this).resourceManager.getStringSync($r('app.string.disk')) if (result) { this.cacheUpLimit = result / (1024 * 1024); + } else { + this.cacheUpLimit = 0; } }).margin({ bottom: 8 }); Button($r('app.string.get_img_number_of_disk')).onClick(() => { let result = ImageKnife.getInstance().getCurrentPicturesNum(CacheStrategy.File); + this.markersNumText = getContext(this).resourceManager.getStringSync($r('app.string.disk')) if (result) { this.currentNum = result; + } else { + this.currentNum = 0; } }).margin({ bottom: 8 }); Button($r('app.string.get_cur_disk_size')).onClick(() => { let result = ImageKnife.getInstance().getCurrentCacheSize(CacheStrategy.File); + this.markersSizeText = getContext(this).resourceManager.getStringSync($r('app.string.disk')) if (result) { this.currentSize = result / (1024 * 1024); + } else { + this.currentSize = 0; } }).margin({ bottom: 8 }); } diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index d059311..fc1da84 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -382,15 +382,15 @@ }, { "name": "cur_cache_limit", - "value": "current cache limit:%dM" + "value": "%s:current cache limit:%fM" }, { "name": "cur_cache_image_num", - "value": "current cache image number:%d" + "value": "%s:current cache image number:%d" }, { "name": "cur_cache_size", - "value": "current cache size:%dM" + "value": "%s:current cache size:%fM" }, { "name": "load_memory", @@ -487,6 +487,14 @@ { "name": "test_cancel_callback_btn", "value": "test callback of cancel" + }, + { + "name": "memory", + "value": "Memory" + }, + { + "name": "disk", + "value": "Disk" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index 2fed51a..f727a27 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -378,15 +378,15 @@ }, { "name": "cur_cache_limit", - "value": "当前缓存上限:%dM" + "value": "%s:当前缓存上限:%fM" }, { "name": "cur_cache_image_num", - "value": "当前缓存图片数量:%d" + "value": "%s:当前缓存图片数量:%d" }, { "name": "cur_cache_size", - "value": "当前缓存的大小:%dM" + "value": "%s:当前缓存的大小:%fM" }, { "name": "load_memory", @@ -483,6 +483,14 @@ { "name": "test_cancel_callback_btn", "value": "测试加载取消回调接口" + }, + { + "name": "memory", + "value": "内存" + }, + { + "name": "disk", + "value": "磁盘" } ] } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/imageFormatAndSize.test.ets b/entry/src/ohosTest/ets/test/imageFormatAndSize.test.ets index 3faa0a6..fea2a53 100644 --- a/entry/src/ohosTest/ets/test/imageFormatAndSize.test.ets +++ b/entry/src/ohosTest/ets/test/imageFormatAndSize.test.ets @@ -13,7 +13,13 @@ * limitations under the License. */ import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; -import { ImageKnifeOption, ImageKnife, ImageKnifeRequest, ImageKnifeRequestSource } from "@ohos/imageknife" +import { + ImageKnifeOption, + ImageKnife, + ImageKnifeRequest, + ImageKnifeRequestSource, + CacheStrategy +} from "@ohos/imageknife" import { common } from '@kit.AbilityKit'; export default function imageFormatAndSize() { @@ -41,16 +47,14 @@ export default function imageFormatAndSize() { let width = 0; let height = 0; let imageFormat: string = ""; - + let url: string = + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg" let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ - loadSrc: $r('app.media.icon'), + loadSrc: url, }) await new Promise((resolve, reject) => { imageKnifeOption.onLoadListener = { onLoadSuccess: (data, imageknifeData) => { - width = imageknifeData.imageWidth - height = imageknifeData.imageHeight - imageFormat = imageknifeData.type! resolve("") }, onLoadFailed(err) { @@ -70,9 +74,16 @@ export default function imageFormatAndSize() { ) ImageKnife.getInstance().execute(request); }) + let data = await ImageKnife.getInstance() + .getCacheImage(url, CacheStrategy.Memory); + if (data) { + width = data.imageWidth + height = data.imageHeight + imageFormat = data.type! + } expect(width != 0).assertTrue(); expect(height != 0).assertTrue(); expect(imageFormat != "").assertTrue(); }); }); -} +} \ No newline at end of file From 55943f1f843fc2d0bb73e7de68bd888db15a57b8 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Thu, 17 Oct 2024 17:04:18 +0800 Subject: [PATCH 6/9] update code because of use image url Signed-off-by: tyBrave --- entry/src/main/ets/pages/TestLoadCancelListenerPage.ets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets b/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets index 9e88f92..5e97810 100644 --- a/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets +++ b/entry/src/main/ets/pages/TestLoadCancelListenerPage.ets @@ -35,7 +35,7 @@ struct TestLoadCancelListenerPage { .margin(20) .onClick(() => { this.ImageKnifeOption = new ImageKnifeOption({ - loadSrc: "https://q7.itc.cn/images01/20240223/ce80229bf9934dff97cdf2ad7be1dcb8.jpeg", + loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg", objectFit: ImageFit.Contain, onLoadListener: { onLoadStart: () => { From 8dd15356468e1a31f4b1351b68ce0aa8ce47cb25 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 23 Oct 2024 16:24:41 +0800 Subject: [PATCH 7/9] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=9B=9E=E8=B0=83=E7=9A=84demo=E5=8F=8A?= =?UTF-8?q?=E5=85=B6xts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- entry/src/main/ets/pages/Index.ets | 7 + .../ets/pages/TestImageKnifeCallbackPage.ets | 286 ++++++++++++++++++ .../pages/TestListImageKnifeCallbackPage.ets | 101 +++++++ .../main/resources/base/element/string.json | 52 ++++ .../resources/base/profile/main_pages.json | 4 +- .../main/resources/zh_CN/element/string.json | 52 ++++ entry/src/ohosTest/ets/test/List.test.ets | 2 + .../ets/test/loadCallBackData.test.ets | 117 +++++++ 8 files changed, 620 insertions(+), 1 deletion(-) create mode 100644 entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets create mode 100644 entry/src/main/ets/pages/TestListImageKnifeCallbackPage.ets create mode 100644 entry/src/ohosTest/ets/test/loadCallBackData.test.ets diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 45db76e..3ee4b9e 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -174,6 +174,13 @@ struct Index { uri: 'pages/TestLoadCancelListenerPage', }); }) + + Button($r('app.string.test_callback')).margin({ top: 10 }).onClick(() => { + router.push({ + uri: 'pages/TestImageKnifeCallbackPage', + + }); + }) } }.width('100%') .height('100%') diff --git a/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets b/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets new file mode 100644 index 0000000..d7b66f3 --- /dev/null +++ b/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets @@ -0,0 +1,286 @@ +/* + * 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, ImageKnifeOption } from '@ohos/imageknife'; +import { router } from '@kit.ArkUI'; + +@Entry +@ComponentV2 +struct TestImageKnifeCallbackPage { + @Local imageKnifeOption: ImageKnifeOption = new ImageKnifeOption(); + @Local currentWidth: number = 200 + @Local currentHeight: number = 200 + @Local startCallBackData: string = "" + @Local successBackData: string = "" + @Local failedBackData: string = "" + @Local cancelBackData: string = "" + @Local render_success: string = "" + @Local showChild: boolean = true; + + build() { + Scroll() { + Column() { + Text($r('app.string.start_callback', this.startCallBackData)) + Text($r('app.string.success_callback', this.successBackData)) + Text($r('app.string.failed_callback', this.failedBackData)) + Text($r('app.string.cancel_callback', this.cancelBackData)) + Text($r('app.string.render_success', this.render_success)) + + Row() { + Button($r('app.string.Network_images')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg", + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + this.successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + + Button($r('app.string.gif')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: 'https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658', + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + let suc = imageData; + suc.source = "" + this.successBackData = JSON.stringify(suc); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + console.log("sss--->gif onComplete:" + JSON.stringify(event)) + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + Button($r('app.string.local_pic')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: $r('app.media.pngSample'), + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + this.successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + } + + Row() { + Button($r('app.string.net_load_failed')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: "https://img-blog.csdn.net/20140514114039140", + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + this.successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + + Button($r('app.string.local_load_failed')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: 'abd', + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + let suc = imageData; + suc.source = "" + this.successBackData = JSON.stringify(suc); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + Button($r('app.string.share_load_failed')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: 'datashare://ssas', + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + this.successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + } + + Button($r('app.string.test_cancel_callback_btn')) + .fontSize(13) + .onClick(() => { + this.destroy(); + this.imageKnifeOption = new ImageKnifeOption({ + loadSrc: "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg", + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + this.startCallBackData = JSON.stringify(data); + this.showChild = false; + }, + onLoadFailed: (res, err) => { + this.failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + this.successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + this.cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + this.render_success = JSON.stringify(Date.now()) + } + } + }) + }) + + Button($r('app.string.list_pic')) + .fontSize(13) + .onClick(() => { + router.push({ + url: 'pages/TestListImageKnifeCallbackPage', + }); + }) + if (this.showChild) { + ImageKnifeComponent( + { imageKnifeOption: this.imageKnifeOption }) + .height(this.currentHeight) + .width(this.currentWidth) + .margin({ top: 20, bottom: 20 }) + + } + } + .width('100%') + } + } + + destroy() { + this.startCallBackData = ""; + this.successBackData = ""; + this.failedBackData = ""; + this.cancelBackData = ""; + this.render_success = ""; + } +} \ No newline at end of file diff --git a/entry/src/main/ets/pages/TestListImageKnifeCallbackPage.ets b/entry/src/main/ets/pages/TestListImageKnifeCallbackPage.ets new file mode 100644 index 0000000..a6d2594 --- /dev/null +++ b/entry/src/main/ets/pages/TestListImageKnifeCallbackPage.ets @@ -0,0 +1,101 @@ +/* + * 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, ImageKnifeOption } from '@ohos/imageknife'; + +class ArrayElement { + src: string = ""; + w: number = 0; + h: number = 0; +} + +@Entry +@Component +struct TestListImageKnifeCallbackPage { + private wid: number = 200; + private hig: number = 200; + private dataArray: ESObject[] = [ + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/56/v3/8MdhfSsCSMKj4sA6okUWrg/5uBx56tLTUO3RYQl-E5JiQ.jpg", + "https://gd-hbimg.huaban.com/e0a25a7cab0d7c2431978726971d61720732728a315ae-57EskW_fw658", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/78/v3/qQJpAtRGQe2e_VhbGHDgIw/b3zlit99S6GybD3XdNwqJw.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/55/v3/5DZ2LLqYSsK85-shqgLveQ/7ZXcyCWNTvOzQP5FFLBGkg.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/3e/v3/LqRoLI-PRSu9Nqa8KdJ-pQ/dSqskBpSR9eraAMn7NBdqA.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/25/v3/jgB2ekkTRX-3yTYZalnANQ/xff_x9cbSPqb7fbNwgJa7A.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/fb/v3/alXwXLHKSyCAIWt_ydgD2g/BCCuu25TREOitQxM7eYOEw.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/16/v3/fm2tO4TsRH6mv_D_nSSd5w/FscLpLwQQ-KuV7oaprFK2Q.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/89/v3/UAUvtPHqRD-GWWANsEC57Q/zcRJCQebQ322Aby4jzmwmQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/30/v3/tUUzzx73R4yp8G--lMhuWQ/EBbcu_dLTT-Jj68XAh6mtA.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/76/v3/EyF6z4FISpCHhae38eEexw/OtyAiu-zSSevNQYvUdtVmA.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/37/v3/12rH1yiEQmK9wlOOcy5avQ/RzBXiEBRRqOC7LRkwNj6VA.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/9a/v3/TpRN4AIzRoyUXIqWdKoE0g/ShOnD_tfS46HDbpSWhbCkQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/03/v3/H3X17s8eTdS2w56JgbB5jQ/a45sT-j8Sbe8sSQXTzeYvQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/10/v3/qaEzwkU0QeKb1yehnP2Xig/q7fxAlgMQKup-HUBayRLGQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/96/v3/rMJJoAflTDSWa1z2pHs2wg/8dOqD0GlQBOCL5AvQok9FQ.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/ed/v3/KMO4D6D2QGuVOCLX4AhOFA/ef51xAaLQuK7BsnuD9abog.jpg", + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/d9/v3/FSZH0aTdSqWxeAaxoPvi0g/RqxPxUCXQFiTMBfKTF9kkw.jpg", + "https://hbimg.huabanimg.com/cc6af25f8d782d3cf3122bef4e61571378271145735e9-vEVggB", + 'https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/bf/v3/lSjrRwFcS-ez6jp1ALSQFg/0n7R7XinSPyrYLqDu_1dfw.jpg', + 'https://img-blog.csdn.net/20140514114029140', + 'https://hbimg.huabanimg.com/95a6d37a39aa0b70d48fa18dc7df8309e2e0e8e85571e-x4hhks_fw658/format/webp', + $r('app.media.pngSample'), + $r('app.media.rabbit') + ] + private data: Array = []; + + aboutToAppear(): void { + for (let i = 0; i < this.dataArray.length; i++) { + let element: ArrayElement = { + src: this.dataArray[i], + w: this.wid -(i*5), + h: this.hig -(i*5) + } + this.data.push(element); + } + } + + build() { + List({ space: 3 }) { + ForEach(this.data, (item: ArrayElement) => { + ListItem() { + ImageKnifeComponent({ + imageKnifeOption: new ImageKnifeOption( + { + loadSrc: item.src, + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + console.log("listCache start:" + JSON.stringify(data)) + }, + onLoadFailed: (res, err) => { + console.log("listCache onLoadFailed:res:" + res + ";" + JSON.stringify(err)) + }, + onLoadSuccess: (data, imageData) => { + console.log("listCache onLoadSuccess:" + JSON.stringify(imageData)) + }, + onLoadCancel: (res, cel) => { + console.log("listCache onLoadCancel:res:" + res + ";" + JSON.stringify(cel)) + } + }, + border: { radius: 50 }, + } + ) + }).height(item.w).width(item.h) + }.width('100%') + }, (item: ArrayElement,index) => (item.src+index)) + }.width('100%').height('100%') + } +} \ No newline at end of file diff --git a/entry/src/main/resources/base/element/string.json b/entry/src/main/resources/base/element/string.json index fc1da84..73528e5 100644 --- a/entry/src/main/resources/base/element/string.json +++ b/entry/src/main/resources/base/element/string.json @@ -488,6 +488,10 @@ "name": "test_cancel_callback_btn", "value": "test callback of cancel" }, + { + "name": "test_callback", + "value": "test callback data of load pic" + }, { "name": "memory", "value": "Memory" @@ -495,6 +499,54 @@ { "name": "disk", "value": "Disk" + }, + { + "name": "start_callback", + "value": "startCallBack:%s" + }, + { + "name": "success_callback", + "value": "successCallBack:%s" + }, + { + "name": "failed_callback", + "value": "failedCallBack:%s" + }, + { + "name": "cancel_callback", + "value": "cancelCallBack:%s" + }, + { + "name": "render_success", + "value": "render success time point:%s" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "local_pic", + "value": "local picture" + }, + { + "name": "share_pic", + "value": "share picture" + }, + { + "name": "net_load_failed", + "value": "netWork load failed" + }, + { + "name": "local_load_failed", + "value": "local load failed" + }, + { + "name": "share_load_failed", + "value": "shared load failed" + }, + { + "name": "list_pic", + "value": "load picture list" } ] } \ No newline at end of file diff --git a/entry/src/main/resources/base/profile/main_pages.json b/entry/src/main/resources/base/profile/main_pages.json index 35d7d51..c426d47 100644 --- a/entry/src/main/resources/base/profile/main_pages.json +++ b/entry/src/main/resources/base/profile/main_pages.json @@ -25,6 +25,8 @@ "pages/TestTaskResourcePage", "pages/TestCacheDataPage", "pages/TestChangeColorPage", - "pages/TestLoadCancelListenerPage" + "pages/TestLoadCancelListenerPage", + "pages/TestImageKnifeCallbackPage", + "pages/TestListImageKnifeCallbackPage" ] } \ No newline at end of file diff --git a/entry/src/main/resources/zh_CN/element/string.json b/entry/src/main/resources/zh_CN/element/string.json index f727a27..6f287d6 100644 --- a/entry/src/main/resources/zh_CN/element/string.json +++ b/entry/src/main/resources/zh_CN/element/string.json @@ -484,6 +484,10 @@ "name": "test_cancel_callback_btn", "value": "测试加载取消回调接口" }, + { + "name": "test_callback", + "value": "测试图片加载回调数据" + }, { "name": "memory", "value": "内存" @@ -491,6 +495,54 @@ { "name": "disk", "value": "磁盘" + }, + { + "name": "start_callback", + "value": "开始回调:%s" + }, + { + "name": "success_callback", + "value": "成功回调:%s" + }, + { + "name": "failed_callback", + "value": "失败回调:%s" + }, + { + "name": "cancel_callback", + "value": "取消回调:%s" + }, + { + "name": "render_success", + "value": "渲染成功时间点:%s" + }, + { + "name": "gif", + "value": "gif" + }, + { + "name": "local_pic", + "value": "本地图片" + }, + { + "name": "share_pic", + "value": "共享图片" + }, + { + "name": "net_load_failed", + "value": "网络加载失败" + }, + { + "name": "local_load_failed", + "value": "本地加载失败" + }, + { + "name": "share_load_failed", + "value": "共享图片加载失败" + }, + { + "name": "list_pic", + "value": "加载图片列表" } ] } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/List.test.ets b/entry/src/ohosTest/ets/test/List.test.ets index 1b17e5f..6c389ee 100644 --- a/entry/src/ohosTest/ets/test/List.test.ets +++ b/entry/src/ohosTest/ets/test/List.test.ets @@ -19,6 +19,7 @@ import MemoryLruCacheTest from './MemoryLruCache.test'; import ImageKnifeTest from './ImageKnife.test'; import Transform from './transform.test'; import imageFormatAndSize from './imageFormatAndSize.test' +import loadCallBackData from './loadCallBackData.test' export default function testsuite() { MemoryLruCacheTest(); @@ -28,4 +29,5 @@ export default function testsuite() { ImageKnifeTest(); Transform(); imageFormatAndSize(); + loadCallBackData(); } \ No newline at end of file diff --git a/entry/src/ohosTest/ets/test/loadCallBackData.test.ets b/entry/src/ohosTest/ets/test/loadCallBackData.test.ets new file mode 100644 index 0000000..a3af0ce --- /dev/null +++ b/entry/src/ohosTest/ets/test/loadCallBackData.test.ets @@ -0,0 +1,117 @@ +/* + * 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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; +import { + ImageKnifeOption, + ImageKnife, + ImageKnifeRequest, + ImageKnifeRequestSource, + CacheStrategy +} from "@ohos/imageknife" +import { common } from '@kit.AbilityKit'; + +export default function loadCallBackData() { + describe('loadCallBackData', () => { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(() => { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(() => { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(() => { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(() => { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('startAndSuccess-CallBack', 0, async () => { + let startCallBack: ESObject = undefined; + let successCallBack: ESObject = undefined; + let url: string = + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/63/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg" + let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ + loadSrc: url, + }) + await new Promise((resolve, reject) => { + imageKnifeOption.onLoadListener = { + onLoadStart: (data) => { + startCallBack = data; + }, + onLoadSuccess: (data, imageknifeData) => { + successCallBack = imageknifeData; + resolve("") + }, + onLoadFailed(err) { + reject(err) + } + } + let request = new ImageKnifeRequest( + imageKnifeOption, + imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext, + 0, + 0, + 0, + { + showPixelMap(version: number, pixelMap: PixelMap | string) { + } + } + ) + ImageKnife.getInstance().execute(request); + }) + expect(startCallBack != undefined).assertTrue(); + expect(successCallBack != undefined).assertTrue(); + }); + it('failed-CallBack', 0, async () => { + let failedCallBack: ESObject = undefined; + let url: string = + "https://contentcenter-drcn.dbankcdn.cn/pub_1/DevEcoSpace_1_900_9/163/v3/qbe6NZkCQyGcITvdWoZBgg/Y-5U1z3GT_yaK8CBD3jkwg.jpg" + let imageKnifeOption: ImageKnifeOption = new ImageKnifeOption({ + loadSrc: url, + }) + await new Promise((resolve, reject) => { + imageKnifeOption.onLoadListener = { + onLoadStart: (data) => { + }, + onLoadSuccess: (data, imageknifeData) => { + }, + onLoadFailed(res,err) { + failedCallBack = err; + resolve(res) + } + } + let request = new ImageKnifeRequest( + imageKnifeOption, + imageKnifeOption.context !== undefined ? imageKnifeOption.context : getContext() as common.UIAbilityContext, + 0, + 0, + 0, + { + showPixelMap(version: number, pixelMap: PixelMap | string) { + } + } + ) + ImageKnife.getInstance().execute(request); + }) + expect(failedCallBack != undefined).assertTrue(); + }); + }); +} \ No newline at end of file From 2d0b6ace7b984168415bef885686ad0d1ec78a7e Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 23 Oct 2024 16:40:06 +0800 Subject: [PATCH 8/9] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E5=8A=A0=E8=BD=BD=E5=9B=9E=E8=B0=83=E7=9A=84=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- .../ets/pages/TestImageKnifeCallbackPage.ets | 1 - library/oh-package-lock.json5 | 6 - library/src/main/ets/ImageKnifeDispatcher.ets | 357 +++++++++++++----- library/src/main/ets/ImageKnifeLoader.ets | 284 ++++++++++---- .../ets/components/ImageKnifeComponent.ets | 44 ++- library/src/main/ets/model/ImageKnifeData.ets | 63 +++- .../src/main/ets/model/ImageKnifeOption.ets | 46 ++- .../src/main/ets/model/ImageKnifeRequest.ets | 28 +- library/src/main/ets/utils/Constants.ets | 50 +++ 9 files changed, 658 insertions(+), 221 deletions(-) delete mode 100644 library/oh-package-lock.json5 diff --git a/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets b/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets index d7b66f3..f6dae0c 100644 --- a/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets +++ b/entry/src/main/ets/pages/TestImageKnifeCallbackPage.ets @@ -94,7 +94,6 @@ struct TestImageKnifeCallbackPage { }, border: { radius: 50 }, onComplete: (event) => { - console.log("sss--->gif onComplete:" + JSON.stringify(event)) if (event && event.loadingStatus == 0) { this.render_success = JSON.stringify(Date.now()) } diff --git a/library/oh-package-lock.json5 b/library/oh-package-lock.json5 deleted file mode 100644 index 3245bae..0000000 --- a/library/oh-package-lock.json5 +++ /dev/null @@ -1,6 +0,0 @@ -{ - "lockfileVersion": 3, - "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", - "specifiers": {}, - "packages": {} -} \ No newline at end of file diff --git a/library/src/main/ets/ImageKnifeDispatcher.ets b/library/src/main/ets/ImageKnifeDispatcher.ets index fbbb3a8..ebb1a43 100644 --- a/library/src/main/ets/ImageKnifeDispatcher.ets +++ b/library/src/main/ets/ImageKnifeDispatcher.ets @@ -19,10 +19,10 @@ import List from '@ohos.util.List'; import LightWeightMap from '@ohos.util.LightWeightMap'; import { LogUtil } from './utils/LogUtil'; import { ImageKnife } from './ImageKnife'; -import { ImageKnifeData, CacheStrategy } from './model/ImageKnifeData'; +import { ImageKnifeData, CacheStrategy, ErrorInfo, TimeInfo } from './model/ImageKnifeData'; import image from '@ohos.multimedia.image'; import emitter from '@ohos.events.emitter'; -import { Constants } from './utils/Constants'; +import { Constants, LoadPhase, LoadPixelMapCode } from './utils/Constants'; import taskpool from '@ohos.taskpool'; import { FileTypeUtil } from './utils/FileTypeUtil'; import { IEngineKey } from './key/IEngineKey'; @@ -46,9 +46,19 @@ export class ImageKnifeDispatcher { executingJobMap: LightWeightMap> = new LightWeightMap(); // 开发者可配置全局缓存 private engineKey: IEngineKey = new DefaultEngineKey(); + //图片加载信息回调数据 + private callBackData: ImageKnifeData = { + source: "", + imageWidth: 0, + imageHeight: 0, + }; + private callBackTimeInfo: TimeInfo = {}; - showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): boolean { - LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" + requestSource + " isAnimator=" + isAnimator) + showFromMemomry(request: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, + requestSource: ImageKnifeRequestSource, isAnimator?: boolean): boolean { + LogUtil.log("ImageKnife_DataTime_showFromMemomry.start:" + request.imageKnifeOption.loadSrc + "requestSource=" + + requestSource + " isAnimator=" + isAnimator) + let memoryCheckStartTime = Date.now(); let memoryCache: ImageKnifeData | undefined; if ((typeof (request.imageKnifeOption.loadSrc as image.PixelMap).isEditable) == 'boolean') { memoryCache = { @@ -58,26 +68,39 @@ export class ImageKnifeDispatcher { } } else { memoryCache = ImageKnife.getInstance() - .loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption,isAnimator)); + .loadFromMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, request.imageKnifeOption, + isAnimator)); + } + //记录ImageKnifeRequestSource.SRC 开始内存检查的时间点 + if (requestSource == ImageKnifeRequestSource.SRC) { + this.callBackTimeInfo.memoryCheckStartTime = memoryCheckStartTime; + this.callBackTimeInfo.memoryCheckEndTime = Date.now(); + this.callBackData.timeInfo = this.callBackTimeInfo; + //设置请求结束的时间点 + if (memoryCache !== undefined) { + this.callBackData.timeInfo.requestEndTime = Date.now(); + } } - if (memoryCache !== undefined) { // 画主图 if (request.requestState === ImageKnifeRequestState.PROGRESS) { // 回调请求开始 - if (requestSource === ImageKnifeRequestSource.SRC && request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { - request.imageKnifeOption.onLoadListener.onLoadStart() + if (requestSource === ImageKnifeRequestSource.SRC && + request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { + request.imageKnifeOption.onLoadListener.onLoadStart(this.callBackData) LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadStart:" + request.imageKnifeOption.loadSrc) } LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.start:" + request.imageKnifeOption.loadSrc) - request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource,memoryCache.imageAnimator) + request.ImageKnifeRequestCallback?.showPixelMap(request.componentVersion, memoryCache.source, requestSource, + memoryCache.imageAnimator) LogUtil.log("ImageKnife_DataTime_MemoryCache_showPixelMap.end:" + request.imageKnifeOption.loadSrc) if (requestSource == ImageKnifeRequestSource.SRC) { request.requestState = ImageKnifeRequestState.COMPLETE // 回调请求开结束 if (request.imageKnifeOption.onLoadListener?.onLoadSuccess !== undefined) { - request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source,memoryCache) + this.copyCallBackData(this.callBackData, memoryCache); + request.imageKnifeOption.onLoadListener.onLoadSuccess(memoryCache.source, memoryCache) LogUtil.log("ImageKnife_DataTime_MemoryCache_onLoadSuccess:" + request.imageKnifeOption.loadSrc) } } else if (requestSource == ImageKnifeRequestSource.ERROR_HOLDER) { @@ -91,15 +114,53 @@ export class ImageKnifeDispatcher { return false } + /** + * 设置进入线程前加载图片的callBack信息 + * @param beforeCallData + * @param afterCallData + */ + private copyCallBackData(beforeCallData: ImageKnifeData | undefined, afterCallData: ImageKnifeData) { + if (!beforeCallData || !afterCallData) { + return; + } + //设置组件宽高 + afterCallData.componentWidth = beforeCallData.componentWidth; + afterCallData.componentHeight = beforeCallData.componentWidth; + //设置图片开始加载时间及其缓存检查时间点 + if (beforeCallData.timeInfo) { + if (afterCallData.timeInfo) { + afterCallData.timeInfo.requestStartTime = beforeCallData.timeInfo.requestStartTime; + afterCallData.timeInfo.memoryCheckStartTime = beforeCallData.timeInfo.memoryCheckStartTime; + afterCallData.timeInfo.memoryCheckEndTime = beforeCallData.timeInfo.memoryCheckEndTime; + } else { + afterCallData.timeInfo = beforeCallData.timeInfo; + } + } + } - enqueue(request: ImageKnifeRequest,isAnimator?: boolean): void { + + enqueue(request: ImageKnifeRequest, isAnimator?: boolean): void { + + if (typeof request.imageKnifeOption.loadSrc == "string") { + this.callBackData.source = request.imageKnifeOption.loadSrc; + } + this.callBackData.componentWidth = request.componentWidth; + this.callBackData.componentHeight = request.componentHeight; + this.callBackTimeInfo.requestStartTime = Date.now(); //1.内存有的话直接渲染 - if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator)) { + if (this.showFromMemomry(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, isAnimator)) { return } + + //这里对this.callBackData要进行深拷贝 + let call = JSON.parse(JSON.stringify(this.callBackData)) as ImageKnifeData; + + //跟隨請求保存回調信息點 + request.setImageKnifeData(call); // 2.内存获取占位图 if (request.imageKnifeOption.placeholderSrc !== undefined) { - if (this.showFromMemomry(request, request.imageKnifeOption.placeholderSrc, ImageKnifeRequestSource.PLACE_HOLDER)) { + if (this.showFromMemomry(request, request.imageKnifeOption.placeholderSrc, + ImageKnifeRequestSource.PLACE_HOLDER)) { request.drawPlayHolderSuccess = true } } @@ -108,10 +169,10 @@ export class ImageKnifeDispatcher { this.jobQueue.add(request) return } - this.executeJob(request,isAnimator) + this.executeJob(request, isAnimator) } - executeJob(request: ImageKnifeRequest,isAnimator?: boolean): void { + executeJob(request: ImageKnifeRequest, isAnimator?: boolean): void { LogUtil.log("ImageKnife_DataTime_executeJob.start:" + request.imageKnifeOption.loadSrc) // 加载占位符 if (request.imageKnifeOption.placeholderSrc !== undefined && request.drawPlayHolderSuccess == false) { @@ -119,16 +180,18 @@ export class ImageKnifeDispatcher { } // 加载主图 - this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC,isAnimator) + this.getAndShowImage(request, request.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, isAnimator) LogUtil.log("ImageKnife_DataTime_executeJob.end:" + request.imageKnifeOption.loadSrc) } /** * 获取和显示图片 */ - getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean): void { + getAndShowImage(currentRequest: ImageKnifeRequest, imageSrc: string | PixelMap | Resource, + requestSource: ImageKnifeRequestSource, isAnimator?: boolean): void { LogUtil.log("ImageKnife_DataTime_getAndShowImage.start:" + currentRequest.imageKnifeOption.loadSrc) - let memoryKey: string = this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator) + let memoryKey: string = + this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption, isAnimator) let requestList: List | undefined = this.executingJobMap.get(memoryKey) if (requestList == undefined) { requestList = new List() @@ -139,28 +202,29 @@ export class ImageKnifeDispatcher { return } - let isWatchProgress : boolean = false - + let isWatchProgress: boolean = false // 回调请求开始 requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { - if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { - requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart() + if (requestWithSource.source === ImageKnifeRequestSource.SRC && + requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart !== undefined) { + requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadStart(currentRequest.getImageKnifeData()) LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadStart:" + currentRequest.imageKnifeOption.loadSrc) } - if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) { + if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && + requestWithSource.source === ImageKnifeRequestSource.SRC) { isWatchProgress = true } }); let src: string | number = "" let moduleName: string = "" let resName: string = "" - if((imageSrc as Resource).id != undefined) { + if ((imageSrc as Resource).id != undefined) { moduleName = (imageSrc as Resource).moduleName src = (imageSrc as Resource).id - if(src == -1) { + if (src == -1) { resName = (imageSrc as Resource).params![0] } - } else if(typeof imageSrc == "string") { + } else if (typeof imageSrc == "string") { src = imageSrc } let request: RequestJobRequest = { @@ -168,61 +232,65 @@ export class ImageKnifeDispatcher { src: src, headers: currentRequest.imageKnifeOption.headerOption, allHeaders: currentRequest.headers, - componentWidth:currentRequest.componentWidth, - componentHeight:currentRequest.componentHeight, + componentWidth: currentRequest.componentWidth, + componentHeight: currentRequest.componentHeight, customGetImage: currentRequest.imageKnifeOption.customGetImage, onlyRetrieveFromCache: currentRequest.imageKnifeOption.onlyRetrieveFromCache, transformation: currentRequest.imageKnifeOption.transformation, writeCacheStrategy: ImageKnife.getInstance() - .isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy : CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存 + .isFileCacheInit() ? currentRequest.imageKnifeOption.writeCacheStrategy : + CacheStrategy.Memory, // 未初始化文件缓存时,不写文件缓存 engineKey: this.engineKey, signature: currentRequest.imageKnifeOption.signature, requestSource: requestSource, isWatchProgress: isWatchProgress, memoryKey: memoryKey, fileCacheFolder: ImageKnife.getInstance().getFileCache()?.getCacheFolder(), - isAnimator:isAnimator, + isAnimator: isAnimator, moduleName: moduleName == "" ? undefined : moduleName, resName: resName == "" ? undefined : resName } - if(request.customGetImage == undefined) { + if (request.customGetImage == undefined) { request.customGetImage = ImageKnife.getInstance().getCustomGetImage() } - if (ImageKnife.getInstance().isRequestInSubThread){ + if (ImageKnife.getInstance().isRequestInSubThread) { // 启动线程下载和解码主图 LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.start:" + currentRequest.imageKnifeOption.loadSrc) let task = new taskpool.Task(requestJob, request) LogUtil.log("ImageKnife_DataTime_getAndShowImage_Task.end:" + currentRequest.imageKnifeOption.loadSrc) - if (isWatchProgress){ + if (isWatchProgress) { emitter.on(Constants.PROGRESS_EMITTER + memoryKey, (data) => { - this.progressCallBack(requestList! , data?.data?.value as number) + this.progressCallBack(requestList!, data?.data?.value as number) }); } - LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(subthread):" + currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(subthread):" + + currentRequest.imageKnifeOption.loadSrc) taskpool.execute(task).then((res: Object) => { - this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator); - if (isWatchProgress){ + this.doTaskCallback(res as RequestJobResult | undefined, requestList!, currentRequest, memoryKey, imageSrc, + requestSource, isAnimator); + if (isWatchProgress) { emitter.off(Constants.PROGRESS_EMITTER + memoryKey) } - LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc) - LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:" + currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc) }).catch((err: BusinessError) => { LogUtil.error("Fail to requestJob in sub thread src=" + imageSrc + " err=" + err) LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc) - if (isWatchProgress){ + if (isWatchProgress) { emitter.off(Constants.PROGRESS_EMITTER + memoryKey) } this.executingJobMap.remove(memoryKey); this.dispatchNextJob(); }) } else { //主线程请求 - LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" + currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.start(mainthread):" + + currentRequest.imageKnifeOption.loadSrc) requestJob(request, requestList).then((res: RequestJobResult | undefined) => { - this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource,isAnimator); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:"+currentRequest.imageKnifeOption.loadSrc) - LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:"+currentRequest.imageKnifeOption.loadSrc) + this.doTaskCallback(res, requestList!, currentRequest, memoryKey, imageSrc, requestSource, isAnimator); + LogUtil.log("ImageKnife_DataTime_getAndShowImage_execute.end:" + currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc) }).catch((err: BusinessError) => { LogUtil.error("Fail to requestJob in main thread src=" + imageSrc + " err=" + err) LogUtil.log("ImageKnife_DataTime_getAndShowImage.end:" + currentRequest.imageKnifeOption.loadSrc) @@ -237,31 +305,52 @@ export class ImageKnifeDispatcher { * @param requestList 请求列表 * @param data 进度 */ - private progressCallBack(requestList:List, data: number) { + private progressCallBack(requestList: List, data: number) { for (let i = 0; i < requestList.length; i++) { - let requestWithSource:ImageKnifeRequestWithSource = requestList[i] - if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) { + let requestWithSource: ImageKnifeRequestWithSource = requestList[i] + if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && + requestWithSource.source === ImageKnifeRequestSource.SRC) { requestWithSource.request.imageKnifeOption.progressListener(data) } } } - private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List , - currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, requestSource: ImageKnifeRequestSource,isAnimator?: boolean):void { - LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.start:"+currentRequest.imageKnifeOption.loadSrc) - if (requestJobResult === undefined){ + private doTaskCallback(requestJobResult: RequestJobResult | undefined, requestList: List, + currentRequest: ImageKnifeRequest, memoryKey: string, imageSrc: string | PixelMap | Resource, + requestSource: ImageKnifeRequestSource, isAnimator?: boolean): void { + LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.start:" + currentRequest.imageKnifeOption.loadSrc) + if (requestJobResult === undefined) { return } + //设置请求结束的时间 + if (requestJobResult.callBackData && requestJobResult.callBackData.timeInfo) { + requestJobResult.callBackData.timeInfo.requestEndTime = Date.now(); + } + let pixelmap = requestJobResult.pixelMap; if (pixelmap === undefined) { - LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.pixelmap undefined:" + + currentRequest.imageKnifeOption.loadSrc) requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { + + //设置失败回调的时间点 + if (requestJobResult.errorCallBackData && requestJobResult.errorCallBackData.timeInfo) { + requestJobResult.errorCallBackData.timeInfo.requestEndTime = Date.now() + let callBackData = requestWithSource.request.getImageKnifeData(); + if (callBackData && callBackData.timeInfo) { + requestJobResult.errorCallBackData.timeInfo.requestStartTime = callBackData.timeInfo.requestStartTime; + requestJobResult.errorCallBackData.timeInfo.memoryCheckStartTime = + callBackData.timeInfo.memoryCheckStartTime; + requestJobResult.errorCallBackData.timeInfo.memoryCheckEndTime = callBackData.timeInfo.memoryCheckEndTime; + } + } // 回调请求失败 if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadFailed !== undefined && requestJobResult.loadFail) { - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:"+currentRequest.imageKnifeOption.loadSrc) + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadFailed(requestJobResult.loadFail, + requestJobResult.errorCallBackData); + LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadFailed:" + currentRequest.imageKnifeOption.loadSrc) } if (requestWithSource.source === ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.errorholderSrc !== undefined) { @@ -278,36 +367,57 @@ export class ImageKnifeDispatcher { return; } // 保存文件缓存 - if (requestJobResult.bufferSize > 0 && currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) { - LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:"+currentRequest.imageKnifeOption.loadSrc) + if (requestJobResult.bufferSize > 0 && + currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.Memory) { + LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.start:" + + currentRequest.imageKnifeOption.loadSrc) ImageKnife.getInstance().saveWithoutWriteFile(requestJobResult.fileKey, requestJobResult.bufferSize); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveWithoutWriteFile.end:" + + currentRequest.imageKnifeOption.loadSrc) + } + let imageKnifeData: ImageKnifeData; + if (!requestJobResult.callBackData) { + imageKnifeData = { + source: pixelmap!, + imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width, + imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height, + type: requestJobResult.type, + }; + } else { + imageKnifeData = requestJobResult.callBackData; + imageKnifeData.source = pixelmap!; } - let ImageKnifeData: ImageKnifeData = { + if (requestJobResult.pixelMapList != undefined) { + let imageAnimator: Array = [] + requestJobResult.pixelMapList.forEach((item, index) => { + imageAnimator.push({ + src: requestJobResult.pixelMapList![index], + duration: requestJobResult.delayList![index] + }) + }) + imageKnifeData.imageAnimator = imageAnimator + } + //构建缓存保存的ImageKnifeData + let saveCacheImageData: ImageKnifeData = { source: pixelmap!, imageWidth: requestJobResult.size == undefined ? 0 : requestJobResult.size.width, imageHeight: requestJobResult.size == undefined ? 0 : requestJobResult.size.height, - type:requestJobResult.type - }; - if(requestJobResult.pixelMapList != undefined) { - let imageAnimator: Array = [] - requestJobResult.pixelMapList.forEach((item,index)=>{ - imageAnimator.push({ - src:requestJobResult.pixelMapList![index], - duration:requestJobResult.delayList![index] - }) - }) - ImageKnifeData.imageAnimator = imageAnimator + type: requestJobResult.type, + imageAnimator: imageKnifeData.imageAnimator } // 保存内存缓存 if (currentRequest.imageKnifeOption.writeCacheStrategy !== CacheStrategy.File) { - LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.start:" + + currentRequest.imageKnifeOption.loadSrc) ImageKnife.getInstance() - .saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption,isAnimator), - ImageKnifeData); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:"+currentRequest.imageKnifeOption.loadSrc) + .saveMemoryCache(this.engineKey.generateMemoryKey(imageSrc, requestSource, currentRequest.imageKnifeOption, + isAnimator), + saveCacheImageData); + LogUtil.log("ImageKnife_DataTime_getAndShowImage_saveMemoryCache.end:" + currentRequest.imageKnifeOption.loadSrc) } + + if (requestList !== undefined) { // key相同的request,一起绘制 requestList.forEach((requestWithSource: ImageKnifeRequestWithSource) => { @@ -317,10 +427,12 @@ export class ImageKnifeDispatcher { requestWithSource.source === ImageKnifeRequestSource.ERROR_HOLDER || (requestWithSource.source === ImageKnifeRequestSource.PLACE_HOLDER && requestWithSource.request.requestState === ImageKnifeRequestState.PROGRESS)) { - LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.start:" + + currentRequest.imageKnifeOption.loadSrc) requestWithSource.request.ImageKnifeRequestCallback.showPixelMap(requestWithSource.request.componentVersion, - ImageKnifeData.source, requestWithSource.source,ImageKnifeData.imageAnimator); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:"+currentRequest.imageKnifeOption.loadSrc) + imageKnifeData.source, requestWithSource.source, imageKnifeData.imageAnimator); + LogUtil.log("ImageKnife_DataTime_getAndShowImage_showPixelMap.end:" + + currentRequest.imageKnifeOption.loadSrc) } if (requestWithSource.source == ImageKnifeRequestSource.SRC) { @@ -328,16 +440,38 @@ export class ImageKnifeDispatcher { if (requestWithSource.request.imageKnifeOption.onLoadListener && requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess) { // 回调请求成功 - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(ImageKnifeData.source,ImageKnifeData); - LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:"+currentRequest.imageKnifeOption.loadSrc) + this.copyCallBackData(requestWithSource.request.getImageKnifeData(), imageKnifeData); + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadSuccess(imageKnifeData.source, + imageKnifeData); + LogUtil.log("ImageKnife_DataTime_getAndShowImage_onLoadSuccess:" + + currentRequest.imageKnifeOption.loadSrc) } } else if (requestWithSource.source == ImageKnifeRequestSource.ERROR_HOLDER) { requestWithSource.request.requestState = ImageKnifeRequestState.ERROR; } } else { - if (requestWithSource.source == ImageKnifeRequestSource.SRC && requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) { - // 回调请求成功 - requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed") + if (requestWithSource.source == ImageKnifeRequestSource.SRC && + requestWithSource.request.imageKnifeOption.onLoadListener?.onLoadCancel) { + // 回调请求取消 + //设置失败回调的时间点 + let callBackData = requestWithSource.request.getImageKnifeData(); + + if (requestJobResult.errorCallBackData && requestJobResult.errorCallBackData.timeInfo) { + requestJobResult.errorCallBackData.timeInfo.requestCancelTime = Date.now(); + requestJobResult.errorCallBackData.timeInfo.requestEndTime = Date.now() + requestJobResult.errorCallBackData.phase = LoadPhase.PHASE_WILL_SHOW; + requestJobResult.errorCallBackData.code = LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE; + if (callBackData && callBackData.timeInfo) { + requestJobResult.errorCallBackData.timeInfo.requestStartTime = + callBackData.timeInfo.requestStartTime; + requestJobResult.errorCallBackData.timeInfo.memoryCheckStartTime = + callBackData.timeInfo.memoryCheckStartTime; + requestJobResult.errorCallBackData.timeInfo.memoryCheckEndTime = + callBackData.timeInfo.memoryCheckEndTime; + } + } + requestWithSource.request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed", + requestJobResult.errorCallBackData) } } }); @@ -347,7 +481,7 @@ export class ImageKnifeDispatcher { } else { LogUtil.log("error: no requestlist need to draw for key = " + memoryKey); } - LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.end:"+currentRequest.imageKnifeOption.loadSrc) + LogUtil.log("ImageKnife_DataTime_getAndShowImage_CallBack.end:" + currentRequest.imageKnifeOption.loadSrc) } @@ -358,14 +492,32 @@ export class ImageKnifeDispatcher { if (request === undefined) { LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end:no any job") break // 队列已无任务 - } - else if (request.requestState === ImageKnifeRequestState.PROGRESS) { + } else if (request.requestState === ImageKnifeRequestState.PROGRESS) { LogUtil.log("ImageKnife_DataTime_dispatchNextJob.start executeJob:" + request.imageKnifeOption.loadSrc) this.executeJob(request) LogUtil.log("ImageKnife_DataTime_dispatchNextJob.end executeJob:" + request.imageKnifeOption.loadSrc) break - }else if (request.requestState == ImageKnifeRequestState.DESTROY && request.imageKnifeOption.onLoadListener?.onLoadCancel) { - request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed") + } else if (request.requestState == ImageKnifeRequestState.DESTROY && + request.imageKnifeOption.onLoadListener?.onLoadCancel) { + + //构建回调错误信息 + let callBackData = request.getImageKnifeData(); + let timeInfo: TimeInfo = {}; + timeInfo.requestCancelTime = Date.now(); + timeInfo.requestEndTime = Date.now() + timeInfo.requestCancelTime = Date.now(); + if (callBackData && callBackData.timeInfo) { + timeInfo.requestStartTime = callBackData.timeInfo.requestStartTime; + timeInfo.memoryCheckStartTime = callBackData.timeInfo.memoryCheckStartTime; + timeInfo.memoryCheckEndTime = callBackData.timeInfo.memoryCheckEndTime; + } + let errorInfo: ErrorInfo = { + phase: LoadPhase.PHASE_THREAD_QUEUE, + code: LoadPixelMapCode.IMAGE_LOAD_CANCEL_FAILED_CODE, + timeInfo:timeInfo + }; + + request.imageKnifeOption.onLoadListener.onLoadCancel("component has destroyed", errorInfo) } } } @@ -392,43 +544,56 @@ export class ImageKnifeDispatcher { * @returns */ @Concurrent -async function requestJob(request: RequestJobRequest, requestList?: List): Promise { +async function requestJob(request: RequestJobRequest, + requestList?: List): Promise { LogUtil.log("ImageKnife_DataTime_requestJob.start:" + request.src + " requestSource=" + request.requestSource) - let src = typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src + let src = + typeof request.src == "number" ? request.resName != undefined ? request.resName : request.src + "" : request.src // 生成文件缓存key let fileKey = request.engineKey.generateFileKey(src, request.signature, request.isAnimator) + //定义加载信息回调数据 + let callBackData: ImageKnifeData = { source: "", imageWidth: 0, imageHeight: 0 }; + //定义图片各个阶段错误信息 + let errorCallBackData: ErrorInfo = { code: 0, phase: LoadPhase.PHASE_LOAD } + //获取图片资源 let resBuf: ArrayBuffer try { LogUtil.log("ImageKnife_DataTime_requestJob.getImageArrayBuffer.start:" + request.src) - resBuf = await ImageKnifeLoader.getImageArrayBuffer(request, requestList, fileKey) + resBuf = await ImageKnifeLoader.getImageArrayBuffer(request, requestList, fileKey, callBackData, errorCallBackData) LogUtil.log("ImageKnife_DataTime_requestJob.getImageArrayBuffer.end:" + request.src) } catch (error) { LogUtil.error("ImageKnife_DataTime_requestJob.end: getImageArrayBuffer error " + request.src + " err=" + error) - return ImageKnifeLoader.makeEmptyResult(error) + return ImageKnifeLoader.makeEmptyResult(error, errorCallBackData) } // 获取图片类型 let typeValue = new FileTypeUtil().getFileType(resBuf); - if(typeValue == null) { + if (typeValue == null) { LogUtil.log("ImageKnife_DataTime_requestJob.end: getFileType is null " + request.src) - return ImageKnifeLoader.makeEmptyResult("request is not a valid image source") + return ImageKnifeLoader.makeEmptyResult("request is not a valid image source", errorCallBackData) } - // 解析图片 + LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.start:" + request.src) - let result: RequestJobResult = await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request) + let result: RequestJobResult = + await ImageKnifeLoader.parseImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData) LogUtil.log("ImageKnife_DataTime_requestJob.parseImage.end:" + request.src) // 图形变化 - if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') { + if (request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined && + result?.pixelMap !== undefined && typeof result.pixelMap !== 'string') { LogUtil.log("ImageKnife_DataTime_requestJob.transform.start:" + request.src) - result.pixelMap = await request.transformation?.transform(request.context, result.pixelMap, request.componentWidth, request.componentHeight); + result.pixelMap = await request.transformation?.transform(request.context, result.pixelMap, request.componentWidth, + request.componentHeight); LogUtil.log("ImageKnife_DataTime_requestJob.transform.end:" + request.src) } LogUtil.log("ImageKnife_DataTime_requestJob.end:" + request.src) + + result.callBackData = callBackData; + result.errorCallBackData = errorCallBackData; return result } diff --git a/library/src/main/ets/ImageKnifeLoader.ets b/library/src/main/ets/ImageKnifeLoader.ets index 1c14d0c..a73bba9 100644 --- a/library/src/main/ets/ImageKnifeLoader.ets +++ b/library/src/main/ets/ImageKnifeLoader.ets @@ -14,8 +14,14 @@ */ import { CacheStrategy, + DecodeImageInfo, + ErrorInfo, + ImageKnifeData, ImageKnifeRequestSource, - ImageKnifeRequestWithSource, RequestJobRequest } from './model/ImageKnifeData'; + ImageKnifeRequestWithSource, + RequestJobRequest, + TimeInfo +} from './model/ImageKnifeData'; import List from '@ohos.util.List' import { FileCache } from './cache/FileCache'; import { LogUtil } from './utils/LogUtil'; @@ -28,6 +34,7 @@ import emitter from '@ohos.events.emitter'; import image from '@ohos.multimedia.image'; import { RequestJobResult } from './model/ImageKnifeData' import util from '@ohos.util'; +import { LoadPixelMapCode, LoadPhase } from './utils/Constants'; class RequestData { receiveSize: number = 2000 @@ -39,62 +46,104 @@ class RequestData { */ export class ImageKnifeLoader { static async parseImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, - request: RequestJobRequest): Promise { - if(request.isAnimator) { - return ImageKnifeLoader.parseForAnimatorComponent(resBuf ,typeValue ,fileKey, request) + request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise { + if (request.isAnimator) { + return ImageKnifeLoader.parseForAnimatorComponent(resBuf, typeValue, fileKey, request, callBackData, + errorCallBackData) } if (typeValue === 'gif' || typeValue === 'webp') { - return ImageKnifeLoader.parseAnimatorImage(resBuf ,typeValue ,fileKey , request) - } else if(typeValue == "svg") { - return ImageKnifeLoader.parseSvgImage(resBuf ,typeValue ,fileKey , request) + return ImageKnifeLoader.parseAnimatorImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData) + } else if (typeValue == "svg") { + return ImageKnifeLoader.parseSvgImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData) } - return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request) + return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData) } - static makeEmptyResult(error: string): RequestJobResult{ + static makeEmptyResult(error: string, errorInfo?: ErrorInfo): RequestJobResult { return { pixelMap: undefined, bufferSize: 0, fileKey: '', loadFail: error, + errorCallBackData: errorInfo } } - static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, request: RequestJobRequest):Promise { + static throwError(error: string, errorInfo: ErrorInfo, code: number, timeInfo: TimeInfo) { + errorInfo.code = code + errorInfo.timeInfo = timeInfo; + throw new Error(error); + } + + static async parseNormalImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, + request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise { let resPixelmap: PixelMap | undefined = undefined + let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {} let decodingOptions: image.DecodingOptions = { - editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false, + editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : + false, } let imageSource: image.ImageSource = image.createImageSource(resBuf) - if (imageSource === undefined){ + if (imageSource === undefined) { + errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE; + errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE; return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed") } let size = (await imageSource.getImageInfo()).size + + callBackData.type = typeValue; + callBackData.imageWidth = size.width; + callBackData.imageHeight = size.height; + callBackData.imageSize = resBuf.byteLength; + callBackData.timeInfo = timeInfo; + timeInfo.decodeStartTime = Date.now(); await imageSource.createPixelMap(decodingOptions) .then((pixelmap: PixelMap) => { resPixelmap = pixelmap + timeInfo.decodeEndTime = Date.now(); imageSource.release() }).catch((error: BusinessError) => { imageSource.release() + timeInfo.decodeEndTime = Date.now(); + errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP; + errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE; + errorCallBackData.timeInfo = timeInfo; return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error)) }) + //获取各个pixelMap的大小 + if (resPixelmap && typeof resPixelmap !== "string") { + let decodeImages: Array = []; + let size = (resPixelmap as PixelMap).getImageInfoSync().size; + let decodeImage: DecodeImageInfo = { + contentWidth: size.width, + contentHeight: size.height, + contentSize: (resPixelmap as PixelMap).getPixelBytesNumber() + } + decodeImages.push(decodeImage); + callBackData.decodeImages = decodeImages; + } + return { pixelMap: resPixelmap, bufferSize: resBuf.byteLength, fileKey: fileKey, - size:size, - type:typeValue + size: size, + type: typeValue }; } + static async parseSvgImage(resBuf: ArrayBuffer, typeValue: string, fileKey: string, - request: RequestJobRequest): Promise { - let resPixelmap: PixelMap | undefined = undefined + request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise { + let resPixelMap: PixelMap | undefined = undefined + let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {} let imageSource: image.ImageSource = image.createImageSource(resBuf) - if (imageSource === undefined){ + if (imageSource === undefined) { + errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE; + errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE; return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed") } @@ -110,59 +159,106 @@ export class ImageKnifeLoader { editable: true, desiredSize: defaultSize }; + callBackData.type = typeValue; + callBackData.imageWidth = size.width; + callBackData.imageHeight = size.height; + callBackData.imageSize = resBuf.byteLength; + callBackData.timeInfo = timeInfo; + timeInfo.decodeStartTime = Date.now(); + await imageSource.createPixelMap(opts) - .then((pixelmap: PixelMap) => { - resPixelmap = pixelmap + .then((pixelMap: PixelMap) => { + resPixelMap = pixelMap imageSource.release() }).catch((error: BusinessError) => { imageSource.release() + timeInfo.decodeEndTime = Date.now(); + errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP; + errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE; + errorCallBackData.timeInfo = timeInfo; return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error)) }) + //获取各个pixelMap的大小 + if (resPixelMap && typeof resPixelMap !== "string") { + let decodeImages: Array = []; + let decodeImage: DecodeImageInfo = { + contentWidth: defaultSize.width, + contentHeight: defaultSize.height, + contentSize: (resPixelMap as PixelMap).getPixelBytesNumber() + } + decodeImages.push(decodeImage); + } + return { - pixelMap: resPixelmap, + pixelMap: resPixelMap, bufferSize: resBuf.byteLength, fileKey: fileKey, - type:typeValue + type: typeValue }; } + static async parseAnimatorImage(resBuf: ArrayBuffer, typeValue: string, - fileKey: string,request: RequestJobRequest): Promise { + fileKey: string, request: RequestJobRequest, callBackData: ImageKnifeData, + errorCallBackData: ErrorInfo): Promise { let imageSource: image.ImageSource = image.createImageSource(resBuf) - if (imageSource === undefined){ + if (imageSource === undefined) { + errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE; + errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE; return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed") } let frameCount = await imageSource.getFrameCount() let size = (await imageSource.getImageInfo()).size + callBackData.type = typeValue; + callBackData.frameCount = frameCount; + callBackData.imageWidth = size.width; + callBackData.imageHeight = size.height; + callBackData.imageSize = resBuf.byteLength; imageSource.release() - if(frameCount == undefined || frameCount == 1) { + if (frameCount == undefined || frameCount == 1) { } else { - let base64str = "data:image/" + typeValue + ";base64," + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf)) + let base64str = + "data:image/" + typeValue + ";base64," + new util.Base64Helper().encodeToStringSync(new Uint8Array(resBuf)) return { pixelMap: base64str, bufferSize: resBuf.byteLength, fileKey: fileKey, - size:size, - type:typeValue + size: size, + type: typeValue }; } - return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request) + return ImageKnifeLoader.parseNormalImage(resBuf, typeValue, fileKey, request, callBackData, errorCallBackData) } + // 为AnimatorComponent解析动图 - static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string,request: RequestJobRequest): Promise { + static async parseForAnimatorComponent(resBuf: ArrayBuffer, typeValue: string, fileKey: string, + request: RequestJobRequest, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise { + let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {} + + callBackData.type = typeValue; if (typeValue === 'gif' || typeValue === 'webp') { let imageSource: image.ImageSource = image.createImageSource(resBuf); - if (imageSource === undefined){ + if (imageSource === undefined) { + errorCallBackData.phase = LoadPhase.PHASE_CREATE_SOURCE; + errorCallBackData.code = LoadPixelMapCode.IMAGE_SOURCE_ERROR_CODE; return ImageKnifeLoader.makeEmptyResult("image.createImageSource failed") } let decodingOptions: image.DecodingOptions = { - editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : false, + editable: request.requestSource === ImageKnifeRequestSource.SRC && request.transformation !== undefined ? true : + false, } + callBackData.imageWidth = imageSource.getImageInfoSync().size.width; + callBackData.imageHeight = imageSource.getImageInfoSync().size.height; + callBackData.imageSize = resBuf.byteLength; + let pixelMapList: Array = [] let delayList: Array = [] + timeInfo.decodeStartTime = Date.now(); + let decodeImages: Array = []; await imageSource.createPixelMapList(decodingOptions).then(async (pixelList: Array) => { + timeInfo.decodeEndTime = Date.now(); //sdk的api接口发生变更:从.getDelayTime() 变为.getDelayTimeList() await imageSource.getDelayTimeList().then(delayTimes => { if (pixelList.length > 0) { @@ -173,14 +269,29 @@ export class ImageKnifeLoader { } else { delayList.push(delayTimes[delayTimes.length - 1]) } + //获取各个pixelMap的大小 + let size = pixelList[i].getImageInfoSync().size + let decodeImage: DecodeImageInfo = { + contentWidth: size.width, + contentHeight: size.height, + contentSize: pixelList[i].getPixelBytesNumber() + } + decodeImages.push(decodeImage); } imageSource.release(); } }) }).catch((error: BusinessError) => { + timeInfo.decodeEndTime = Date.now(); imageSource.release() + errorCallBackData.phase = LoadPhase.PHASE_CREATE_PIXEL_MAP; + errorCallBackData.code = LoadPixelMapCode.IMAGE_DECODE_ERROR_CODE; + errorCallBackData.timeInfo = timeInfo; return ImageKnifeLoader.makeEmptyResult(JSON.stringify(error)) }) + callBackData.timeInfo = timeInfo; + callBackData.decodeImages = decodeImages; + errorCallBackData.timeInfo = timeInfo; return { pixelMap: "", bufferSize: resBuf.byteLength, @@ -190,47 +301,59 @@ export class ImageKnifeLoader { delayList } } else { + callBackData.timeInfo = timeInfo; + errorCallBackData.phase = LoadPhase.PHASE_PARSE_IAMGE; + errorCallBackData.timeInfo = timeInfo; + errorCallBackData.code = LoadPixelMapCode.IMAGE_FORMAT_ERROR_CODE return ImageKnifeLoader.makeEmptyResult("ImageKnifeAnimatorComponent组件仅支持动态图") } } // 获取图片资源 - static async getImageArrayBuffer(request: RequestJobRequest, requestList: List | undefined,fileKey:string): Promise { + static async getImageArrayBuffer(request: RequestJobRequest, + requestList: List | undefined, + fileKey: string, callBackData: ImageKnifeData, errorCallBackData: ErrorInfo): Promise { let resBuf: ArrayBuffer | undefined - + let timeInfo: TimeInfo = callBackData.timeInfo ? callBackData.timeInfo : {}; // 判断自定义下载 - if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && typeof request.src == "string") { + if (request.customGetImage !== undefined && request.requestSource == ImageKnifeRequestSource.SRC && + typeof request.src == "string") { // 先从文件缓存获取 - resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder) + timeInfo.diskCheckStartTime = Date.now(); + resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder) + timeInfo.diskCheckEndTime = Date.now(); if (resBuf === undefined) { LogUtil.log("start customGetImage src=" + request.src) try { resBuf = await request.customGetImage(request.context, request.src) LogUtil.log("end customGetImage src=" + request.src) } catch (err) { - throw new Error('customGetImage loadFile failed! err = ' + err) + ImageKnifeLoader.throwError('customGetImage loadFile failed! err = ' + err, + errorCallBackData, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE, timeInfo) } if (resBuf === undefined) { - throw new Error('customGetImage loadFile failed!') + ImageKnifeLoader.throwError('customGetImage loadFile failed!', + errorCallBackData, LoadPixelMapCode.IMAGE_CUSTOM_LOAD_FAILED_CODE, timeInfo) } // 保存文件缓存 - if (request.writeCacheStrategy !== CacheStrategy.Memory) { + if (resBuf && request.writeCacheStrategy !== CacheStrategy.Memory) { LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:" + request.src) FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf, request.fileCacheFolder) LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:" + request.src) } } - } - else { + } else { if (typeof request.src === 'string') { if (request.src.indexOf("http://") == 0 || request.src.indexOf("https://") == 0) { //从网络下载 // 先从文件缓存获取 - resBuf = FileCache.getFileCacheByFile(request.context, fileKey , request.fileCacheFolder) - if (resBuf !== undefined){ + timeInfo.diskCheckStartTime = Date.now() + resBuf = FileCache.getFileCacheByFile(request.context, fileKey, request.fileCacheFolder) + timeInfo.diskCheckEndTime = Date.now() + if (resBuf !== undefined) { LogUtil.log("success get image from filecache for key = " + fileKey + " src = " + request.src) - } - else if (request.onlyRetrieveFromCache != true) { + } else if (request.onlyRetrieveFromCache != true) { LogUtil.log("HttpDownloadClient.start:" + request.src) + timeInfo.netRequestStartTime = Date.now(); let httpRequest = http.createHttp(); let progress: number = 0 let arrayBuffers = new Array() @@ -246,6 +369,11 @@ export class ImageKnifeLoader { } httpRequest.on("dataReceive", (data: ArrayBuffer) => { arrayBuffers.push(data) + //获取http下载的字节数 + if (callBackData.bufSize == undefined) { + callBackData.bufSize = 0; + } + callBackData.bufSize += data.byteLength; }); if (request.isWatchProgress) { @@ -258,10 +386,11 @@ export class ImageKnifeLoader { if (requestList === undefined) { // 子线程 emitter.emit(Constants.PROGRESS_EMITTER + request.memoryKey, { data: { "value": progress } }) - }else { + } else { // 主线程请求 requestList!.forEach((requestWithSource: ImageKnifeRequestWithSource) => { - if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && requestWithSource.source === ImageKnifeRequestSource.SRC) { + if (requestWithSource.request.imageKnifeOption.progressListener !== undefined && + requestWithSource.source === ImageKnifeRequestSource.SRC) { requestWithSource.request.imageKnifeOption.progressListener(progress) } }) @@ -281,42 +410,59 @@ export class ImageKnifeLoader { }); await promise.then((data: number) => { + errorCallBackData.phase = LoadPhase.PHASE_NET + errorCallBackData.httpCode = data; + timeInfo.netRequestEndTime = Date.now(); if (data == 200 || data == 206 || data == 204) { resBuf = combineArrayBuffers(arrayBuffers) } else { - throw new Error("HttpDownloadClient has error, http code =" + JSON.stringify(data)) + ImageKnifeLoader.throwError("HttpDownloadClient has error, http code =" + JSON.stringify(data), + errorCallBackData, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, timeInfo) } }).catch((err: Error) => { - throw new Error("HttpDownloadClient download ERROR : err = " + JSON.stringify(err)) + timeInfo.netRequestEndTime = Date.now(); + ImageKnifeLoader.throwError("HttpDownloadClient download ERROR : err = " + JSON.stringify(err), + errorCallBackData, LoadPixelMapCode.IMAGE_HTTPS_LOAD_FAILED_CODE, timeInfo) }); LogUtil.log("HttpDownloadClient.end:" + request.src) // 保存文件缓存 if (resBuf !== undefined && request.writeCacheStrategy !== CacheStrategy.Memory) { - LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:"+request.src) - FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf , request.fileCacheFolder) - LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:"+request.src) + LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.start:" + request.src) + FileCache.saveFileCacheOnlyFile(request.context, fileKey, resBuf, request.fileCacheFolder) + LogUtil.log("ImageKnife_DataTime_requestJob_saveFileCacheOnlyFile.end:" + request.src) } - } - else { - throw new Error('onlyRetrieveFromCache,do not fetch image src = ' + request.src) + } else { + ImageKnifeLoader.throwError('onlyRetrieveFromCache,do not fetch image src = ' + request.src, + errorCallBackData, LoadPixelMapCode.IMAGE_RETRIEVE_CACHE_CODE, timeInfo) } } else if (request.src.startsWith('datashare://') || request.src.startsWith('file://')) { + errorCallBackData.phase = LoadPhase.PHASE_SHARE_FILE await fs.open(request.src, fs.OpenMode.READ_ONLY).then(async (file) => { - await fs.stat(file.fd).then(async (stat) =>{ + await fs.stat(file.fd).then(async (stat) => { let buf = new ArrayBuffer(stat.size); await fs.read(file.fd, buf).then((readLen) => { resBuf = buf; fs.closeSync(file.fd); - }).catch((err:BusinessError) => { - throw new Error('LoadDataShareFileClient fs.read err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code) + }).catch((err: BusinessError) => { + ImageKnifeLoader.throwError('LoadDataShareFileClient fs.read err happened uri=' + request.src + + " err.msg=" + + err?.message + " err.code=" + err?.code, + errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo) }) - }).catch((err:BusinessError) => { - throw new Error('LoadDataShareFileClient fs.stat err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code) + }).catch((err: BusinessError) => { + ImageKnifeLoader.throwError('LoadDataShareFileClient fs.stat err happened uri=' + request.src + + " err.msg=" + + err?.message + " err.code=" + err?.code, + errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo) }) - }).catch((err:BusinessError) => { - throw new Error('LoadDataShareFileClient fs.open err happened uri=' + request.src + " err.msg=" + err?.message + " err.code=" + err?.code) + }).catch((err: BusinessError) => { + ImageKnifeLoader.throwError('LoadDataShareFileClient fs.open err happened uri=' + request.src + + " err.msg=" + + err?.message + " err.code=" + err?.code, + errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_SHARE_FILE_FAILED_CODE, timeInfo) }) } else { //从本地文件获取 + errorCallBackData.phase = LoadPhase.PHASE_LOCAL_FILE try { let stat = fs.statSync(request.src); if (stat.size > 0) { @@ -326,20 +472,22 @@ export class ImageKnifeLoader { fs.closeSync(file); } } catch (err) { - throw new Error(err) + ImageKnifeLoader.throwError(err, + errorCallBackData, LoadPixelMapCode.IMAGE_LOAD_LOCAL_FILE_FAILED_CODE, timeInfo) } } } else if (typeof request.src == "number") { //从资源文件获取 let manager = request.context.createModuleContext(request.moduleName).resourceManager - if (resBuf == undefined && request.onlyRetrieveFromCache != true && request.requestSource == ImageKnifeRequestSource.SRC) { - if(request.src == -1) { + if (resBuf == undefined && request.onlyRetrieveFromCache != true && + request.requestSource == ImageKnifeRequestSource.SRC) { + if (request.src == -1) { let resName = request.resName as string resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer } else { resBuf = manager.getMediaContentSync(request.src).buffer as ArrayBuffer } } else if (resBuf == undefined && request.requestSource != ImageKnifeRequestSource.SRC) { - if(request.src == -1) { + if (request.src == -1) { let resName = request.resName as string resBuf = (await manager.getMediaByName(resName.substring(10))).buffer as ArrayBuffer } else { @@ -349,9 +497,13 @@ export class ImageKnifeLoader { } } - if (resBuf === undefined){ + if (resBuf === undefined) { + errorCallBackData.code = LoadPixelMapCode.IMAGE_LOAD_FAILED_CODE + errorCallBackData.timeInfo = timeInfo; throw new Error('getImageArrayBuffer undefined') } + callBackData.timeInfo = timeInfo; + errorCallBackData.timeInfo = timeInfo; return resBuf } } \ No newline at end of file diff --git a/library/src/main/ets/components/ImageKnifeComponent.ets b/library/src/main/ets/components/ImageKnifeComponent.ets index f96cecc..b965dd5 100644 --- a/library/src/main/ets/components/ImageKnifeComponent.ets +++ b/library/src/main/ets/components/ImageKnifeComponent.ets @@ -53,23 +53,28 @@ export struct ImageKnifeComponent { aboutToAppear(): void { this.objectFit = this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit - if(this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片 + if (this.syncLoad) { //针对部分消息列表最新消息的图片闪动问题,建议使用同步方式在aboutToAppear时加载图片 let engineKey: IEngineKey = new DefaultEngineKey(); let memoryCacheSrc: ImageKnifeData | undefined = ImageKnife.getInstance() - .loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc,ImageKnifeRequestSource.SRC,this.imageKnifeOption)) - if (memoryCacheSrc !== undefined){ - LogUtil.log("aboutToAppear success load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc) + .loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.loadSrc, ImageKnifeRequestSource.SRC, + this.imageKnifeOption)) + if (memoryCacheSrc !== undefined) { + LogUtil.log("aboutToAppear success load loadSrc from memory cache for loadSrc = " + + this.imageKnifeOption.loadSrc) this.pixelMap = memoryCacheSrc.source; - }else{ - LogUtil.log("aboutToAppear fail load loadSrc from memory cache for loadSrc = "+ this.imageKnifeOption.loadSrc) - if (this.imageKnifeOption.placeholderSrc !== undefined){ + } else { + LogUtil.log("aboutToAppear fail load loadSrc from memory cache for loadSrc = " + this.imageKnifeOption.loadSrc) + if (this.imageKnifeOption.placeholderSrc !== undefined) { let memoryCachePlace: ImageKnifeData | undefined = ImageKnife.getInstance() - .loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!,ImageKnifeRequestSource.PLACE_HOLDER,this.imageKnifeOption)) - if (memoryCachePlace !== undefined){ - LogUtil.log("aboutToAppear success load placeholderSrc from memory cache for placeholderSrc = " + this.imageKnifeOption.placeholderSrc) + .loadFromMemoryCache(engineKey.generateMemoryKey(this.imageKnifeOption.placeholderSrc!, + ImageKnifeRequestSource.PLACE_HOLDER, this.imageKnifeOption)) + if (memoryCachePlace !== undefined) { + LogUtil.log("aboutToAppear success load placeholderSrc from memory cache for placeholderSrc = " + + this.imageKnifeOption.placeholderSrc) this.pixelMap = memoryCachePlace.source; - }else{ - LogUtil.log("aboutToAppear fail load placeholderSrc from memory cache for placeholderSrc = " + this.imageKnifeOption.placeholderSrc) + } else { + LogUtil.log("aboutToAppear fail load placeholderSrc from memory cache for placeholderSrc = " + + this.imageKnifeOption.placeholderSrc) } } } @@ -87,7 +92,7 @@ export struct ImageKnifeComponent { /** * 对已DESTROY的组件不再发起请求 */ - private clearLastRequest(){ + private clearLastRequest() { if (this.request !== undefined) { this.request.requestState = ImageKnifeRequestState.DESTROY this.request = undefined @@ -104,7 +109,7 @@ export struct ImageKnifeComponent { .syncLoad(this.syncLoad) .draggable(false) .onComplete(this.imageKnifeOption.onComplete) - .onSizeChange((oldValue:SizeOptions, newValue:SizeOptions) => { + .onSizeChange((oldValue: SizeOptions, newValue: SizeOptions) => { this.currentWidth = newValue.width as number this.currentHeight = newValue.height as number this.lastWidth = oldValue.width as number @@ -138,7 +143,8 @@ export struct ImageKnifeComponent { height, this.componentVersion, { - showPixelMap: async (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource) => { + showPixelMap: async (version: number, pixelMap: PixelMap | string, + requestSource: ImageKnifeRequestSource) => { if (version !== this.componentVersion) { return //针对reuse场景,不显示历史图片 } @@ -154,10 +160,14 @@ export struct ImageKnifeComponent { this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit } else if (requestSource == ImageKnifeRequestSource.PLACE_HOLDER) { this.objectFit = - this.imageKnifeOption.placeholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.placeholderObjectFit + this.imageKnifeOption.placeholderObjectFit === undefined ? + (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : + this.imageKnifeOption.placeholderObjectFit } else { this.objectFit = - this.imageKnifeOption.errorholderObjectFit === undefined ? (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : this.imageKnifeOption.errorholderObjectFit + this.imageKnifeOption.errorholderObjectFit === undefined ? + (this.imageKnifeOption.objectFit === undefined ? ImageFit.Contain : this.imageKnifeOption.objectFit) : + this.imageKnifeOption.errorholderObjectFit } } }) diff --git a/library/src/main/ets/model/ImageKnifeData.ets b/library/src/main/ets/model/ImageKnifeData.ets index e8a4c2a..3b2731f 100644 --- a/library/src/main/ets/model/ImageKnifeData.ets +++ b/library/src/main/ets/model/ImageKnifeData.ets @@ -20,12 +20,56 @@ import common from '@ohos.app.ability.common'; import { Size } from '@kit.ArkUI' export interface ImageKnifeData { - source: PixelMap | string, - imageWidth: number, + source: PixelMap | string, // url + imageWidth: number, // 原始宽高大小 imageHeight: number, - type?:string, - imageAnimator?: Array + imageSize?: number, + type?: string, + imageAnimator?: Array, + bufSize?: number, // 网络请求字节数 + componentWidth?: number //组件宽高 + componentHeight?: number + frameCount ?: number // 帧 + decodeImages?: Array //Image组件或者ImageAnimator组件可以加载一张或者多张 + timeInfo?: TimeInfo // 加载图片的各个时间点 } + +/** + * 解码后的图片的size + */ +export interface DecodeImageInfo { + contentWidth ?: number // 解码后宽高 + contentHeight?: number + contentSize ?: number // 大小 +} + +/** + * 加载的错误信息 + */ +export interface ErrorInfo { + phase: string, //图片加载阶段信息,如:网络加载阶段,缓存获取阶段及其解码阶段等 + code: number, + timeInfo?: TimeInfo, + httpCode?: number +} + +/** + * lru检查时间点 + */ +export interface TimeInfo { + requestStartTime?: number, + requestEndTime?: number, + requestCancelTime?: number, + memoryCheckStartTime?: number, + memoryCheckEndTime?: number, + diskCheckStartTime?: number, + diskCheckEndTime?: number, + netRequestStartTime?: number, + netRequestEndTime?: number, + decodeStartTime?: number, + decodeEndTime?: number, +} + /** * onComplete成功回调 */ @@ -40,6 +84,7 @@ export interface EventImage { contentOffsetX: number; contentOffsetY: number; } + /** * 缓存策略 */ @@ -75,10 +120,12 @@ export interface RequestJobResult { bufferSize: number fileKey: string loadFail?: string, - size?:Size, + size?: Size, type?: string, - pixelMapList?:Array, - delayList?: Array + pixelMapList?: Array, + delayList?: Array, + callBackData?: ImageKnifeData, + errorCallBackData?: ErrorInfo } /** @@ -102,7 +149,7 @@ export interface RequestJobRequest { memoryKey: string fileCacheFolder: string, isAnimator?: boolean, - moduleName?:string, + moduleName?: string, resName?: string } diff --git a/library/src/main/ets/model/ImageKnifeOption.ets b/library/src/main/ets/model/ImageKnifeOption.ets index 5c5f292..038e936 100644 --- a/library/src/main/ets/model/ImageKnifeOption.ets +++ b/library/src/main/ets/model/ImageKnifeOption.ets @@ -14,7 +14,7 @@ */ import taskpool from '@ohos.taskpool'; import common from '@ohos.app.ability.common' -import { CacheStrategy, ImageKnifeData,EventImage } from './ImageKnifeData'; +import { CacheStrategy, ImageKnifeData, EventImage, ErrorInfo } from './ImageKnifeData'; import { PixelMapTransformation } from '../transform/PixelMapTransformation'; import { drawing } from '@kit.ArkGraphics2D'; @@ -22,16 +22,18 @@ export interface HeaderOptions { key: string; value: Object; } + interface AnimatorType { state?: AnimationStatus iterations?: number reverse?: boolean - onStart?:()=>void - onFinish?:()=>void - onPause?:()=>void - onCancel?:()=>void - onRepeat?:()=>void + onStart?: () => void + onFinish?: () => void + onPause?: () => void + onCancel?: () => void + onRepeat?: () => void } + @ObservedV2 export class AnimatorOption { @Trace @@ -41,16 +43,17 @@ export class AnimatorOption { @Trace reverse?: boolean = false @Trace - onStart?:()=>void + onStart?: () => void @Trace - onFinish?:()=>void + onFinish?: () => void @Trace - onPause?:()=>void + onPause?: () => void @Trace - onCancel?:()=>void + onCancel?: () => void @Trace - onRepeat?:()=>void - constructor(option?:AnimatorType) { + onRepeat?: () => void + + constructor(option?: AnimatorType) { this.state = option?.state this.iterations = option?.iterations this.reverse = option?.reverse @@ -61,6 +64,7 @@ export class AnimatorOption { this.onRepeat = option?.onRepeat } } + interface ImageOption { // 主图资源 loadSrc: string | PixelMap | Resource @@ -69,6 +73,7 @@ interface ImageOption { // 失败占位图 errorholderSrc?: string | PixelMap | Resource headerOption?: Array; + // 自定义缓存关键字 signature?: string // 主图填充效果 @@ -88,9 +93,10 @@ interface ImageOption { progressListener?: (progress: number) => void; transformation?: PixelMapTransformation onLoadListener?: OnLoadCallBack | undefined; - onComplete?:(event:EventImage | undefined) => void + onComplete?: (event: EventImage | undefined) => void drawingColorFilter?: ColorFilter | drawing.ColorFilter } + @ObservedV2 export class ImageKnifeOption { // 主图资源 @@ -119,9 +125,10 @@ export class ImageKnifeOption { progressListener?: (progress: number) => void; @Trace transformation?: PixelMapTransformation onLoadListener?: OnLoadCallBack | undefined; - onComplete?:(event:EventImage | undefined) => void - drawingColorFilter?: ColorFilter | drawing.ColorFilter - constructor(option?:ImageOption) { + onComplete?: (event: EventImage | undefined) => void + drawingColorFilter?: ColorFilter | drawing.ColorFilter | ResourceColor + + constructor(option?: ImageOption) { this.loadSrc = option?.loadSrc == undefined ? "" : option?.loadSrc this.placeholderSrc = option?.placeholderSrc this.errorholderSrc = option?.errorholderSrc @@ -149,13 +156,14 @@ export class ImageKnifeOption { */ export interface OnLoadCallBack { // 请求开始 - onLoadStart?: () => void; + onLoadStart?: (imageKnifeData?: ImageKnifeData) => void; // 请求成功 onLoadSuccess?: (data: string | PixelMap | undefined, imageKnifeData: ImageKnifeData) => void; // 请求结束 - onLoadFailed?: (err: string) => void; + onLoadFailed?: (err: string, errorInfo?: ErrorInfo) => void; + // 请求取消 - onLoadCancel?: (reason: string) => void; + onLoadCancel?: (reason: string, errorInfo?: ErrorInfo) => void; } \ No newline at end of file diff --git a/library/src/main/ets/model/ImageKnifeRequest.ets b/library/src/main/ets/model/ImageKnifeRequest.ets index c63f8be..503d45f 100644 --- a/library/src/main/ets/model/ImageKnifeRequest.ets +++ b/library/src/main/ets/model/ImageKnifeRequest.ets @@ -14,7 +14,7 @@ */ import { ImageKnifeOption } from './ImageKnifeOption'; import common from '@ohos.app.ability.common'; -import { ImageKnifeRequestSource } from './ImageKnifeData'; +import { ImageKnifeData, ImageKnifeRequestSource } from './ImageKnifeData'; export class ImageKnifeRequest { @@ -26,13 +26,15 @@ export class ImageKnifeRequest { context: common.UIAbilityContext ImageKnifeRequestCallback: ImageKnifeRequestCallback componentVersion: number = 0 - headers: Map = new Map() + headers: Map = new Map() + private imageCallBackData: ImageKnifeData | undefined = undefined; + constructor(option: ImageKnifeOption, - uIAbilityContext: common.UIAbilityContext, - width: number, - height: number, - version: number, - ImageKnifeRequestCallback: ImageKnifeRequestCallback) { + uIAbilityContext: common.UIAbilityContext, + width: number, + height: number, + version: number, + ImageKnifeRequestCallback: ImageKnifeRequestCallback) { this.imageKnifeOption = option this.context = uIAbilityContext this.componentWidth = width @@ -40,6 +42,7 @@ export class ImageKnifeRequest { this.componentVersion = version this.ImageKnifeRequestCallback = ImageKnifeRequestCallback } + // RequestOption调用header对于的方法 addHeader(key: string, value: Object) { this.headers.set(key, value); @@ -53,6 +56,14 @@ export class ImageKnifeRequest { } }) } + + setImageKnifeData(data: ImageKnifeData) { + this.imageCallBackData = data; + } + + getImageKnifeData(): ImageKnifeData | undefined { + return this.imageCallBackData + } } export enum ImageKnifeRequestState { @@ -64,5 +75,6 @@ export enum ImageKnifeRequestState { export interface ImageKnifeRequestCallback { - showPixelMap: (version: number, pixelMap: PixelMap | string , requestSource: ImageKnifeRequestSource,imageAnimator?: Array) => void; + showPixelMap: (version: number, pixelMap: PixelMap | string, requestSource: ImageKnifeRequestSource, + imageAnimator?: Array) => void; } diff --git a/library/src/main/ets/utils/Constants.ets b/library/src/main/ets/utils/Constants.ets index d187451..33ba0c8 100644 --- a/library/src/main/ets/utils/Constants.ets +++ b/library/src/main/ets/utils/Constants.ets @@ -14,4 +14,54 @@ */ export class Constants { public static PROGRESS_EMITTER: string = "progressEmitter" +} + +/** + * 图片加载的code + */ +export enum LoadPixelMapCode { + // createImageSource error code + IMAGE_SOURCE_ERROR_CODE = 100001, + // createPixelMap error code + IMAGE_DECODE_ERROR_CODE = 100002, + //ImageKnifeAnimatorComponent组件仅支持动态图 code + IMAGE_FORMAT_ERROR_CODE = 100003, + //load failed code + IMAGE_LOAD_FAILED_CODE = 100004, + //自定义下载失败 code + IMAGE_CUSTOM_LOAD_FAILED_CODE = 100005, + // http请求失败 code + IMAGE_HTTPS_LOAD_FAILED_CODE = 100006, + //设置onlyRetrieveFromCache 导致的加载失败的code + IMAGE_RETRIEVE_CACHE_CODE = 100007, + //加载共享图片失败 + IMAGE_LOAD_SHARE_FILE_FAILED_CODE = 100008, + //加载本地文件图片失败 + IMAGE_LOAD_LOCAL_FILE_FAILED_CODE = 100009, + // 取消请求加载code + IMAGE_LOAD_CANCEL_FAILED_CODE = 1000010 +} + +/** + * 图片加载的各个阶段 + */ +export enum LoadPhase { + // 图片加载阶段 + PHASE_LOAD = "load", + // 网络请求下载阶段 + PHASE_NET = "net", + // createPixelMap 阶段 + PHASE_CREATE_SOURCE = "createImageSource", + //createPixelMap 阶段 + PHASE_CREATE_PIXEL_MAP = "createPixelMap", + //请求队列排队阶段 + PHASE_THREAD_QUEUE = "thread_queue", + //图片解析阶段 + PHASE_PARSE_IAMGE = "parseImage", + //加载解析datashare:// 或者file:// 阶段 + PHASE_SHARE_FILE = "datashare_or_file", + //加载解析本地文件阶段 + PHASE_LOCAL_FILE = "load_local_file", + //图片加载解析完成,即将显示的阶段 + PHASE_WILL_SHOW = "will_show", } \ No newline at end of file From 3b60b9dc74456d97f86b54abc3364f9eee811b49 Mon Sep 17 00:00:00 2001 From: tyBrave Date: Wed, 23 Oct 2024 17:06:15 +0800 Subject: [PATCH 9/9] =?UTF-8?q?=E4=BF=AE=E6=94=B9README=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: tyBrave --- CHANGELOG.md | 3 + README.md | 35 +++++++++- README_zh.md | 103 ++++++++++++++++++---------- library/src/main/ets/ImageKnife.ets | 4 +- 4 files changed, 107 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 794a2f7..324c392 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 3.1.1-rc.1 +- 新增图片加载的回调信息 +- 新增获取当前缓存的上限、大小及其当前对应缓存图片的个数的接口 ## 3.1.1-rc.0 - 重构代码:抽取ImageKnifeDispatcher子线程requestJob相关代码到ImageKnifeLoader中,降低函数复杂度 diff --git a/README.md b/README.md index bf787e0..4889f7d 100644 --- a/README.md +++ b/README.md @@ -264,6 +264,36 @@ ImageKnifeAnimatorComponent({ }),animatorOption:this.animatorOption }).width(300).height(300).backgroundColor(Color.Orange).margin({top:30}) ``` + +#### 11.Load the image callback information data +``` +ImageKnifeComponent({ ImageKnifeOption: = new ImageKnifeOption({ + loadSrc: $r('app.media.pngSample'), + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + let startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + let failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + let successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + let cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + let render_success = JSON.stringify(Date.now()) + } + } + }) +}).width(100).height(100) +``` + #### Reuse Scenario Clear the component content in the **aboutToRecycle** lifecycle and trigger image loading through watch observeration. ## Available APIs @@ -307,7 +337,7 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag | transformation | PixelMapTransformation | Image transformation. Optional. | | drawingColorFilter | ColorFilter | Drawing color filter. Optional. | | onComplete | (event:EventImage \| undefined)=>void | Callback for image loading completion. Optional. | -| onLoadListener | onLoadStart:()=>void,onLoadSuccess:(data:string\|Pixelmap)=>void | Callback for image loading events. Optional. | +| onLoadListener | onLoadStart: (call?: ImageKnifeData) => void、onLoadSuccess: (data: string \| PixelMap \| undefined,call?: ImageKnifeData) => void、onLoadFailed: (err: string,errorInfo?: ErrorInfo) => void | Callback for image loading events. Optional. | ### ImageKnife @@ -325,6 +355,9 @@ Clear the component content in the **aboutToRecycle** lifecycle and trigger imag | putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | Writes to the memory disk cache. | | removeMemoryCache | url: string | Removes an entry from the memory cache. | | removeFileCache | url: string | Removes an entry from the file cache. | +| getCacheUpperLimit | cacheType?: CacheStrategy | Gets the upper limit size of the specified cache | +| getCurrentPicturesNum | cacheType?: CacheStrategy | Gets the number of images currently cached in the specified cache | +| getCurrentCacheSize | cacheType?: CacheStrategy | Gets the current size of the specified cache | ### Graphics tRansformation Types (GPUImage Dependency Required) | Type | Description | diff --git a/README_zh.md b/README_zh.md index 97522da..19a4d5c 100644 --- a/README_zh.md +++ b/README_zh.md @@ -264,6 +264,35 @@ ImageKnifeAnimatorComponent({ }),animatorOption:this.animatorOption }).width(300).height(300).backgroundColor(Color.Orange).margin({top:30}) ``` +#### 11.加载图片回调信息数据 示例 +``` +ImageKnifeComponent({ ImageKnifeOption: = new ImageKnifeOption({ + loadSrc: $r('app.media.pngSample'), + objectFit: ImageFit.Contain, + onLoadListener: { + onLoadStart: (data) => { + let startCallBackData = JSON.stringify(data); + }, + onLoadFailed: (res, err) => { + let failedBackData = res + ";" + JSON.stringify(err); + }, + onLoadSuccess: (data, imageData) => { + let successBackData = JSON.stringify(imageData); + }, + onLoadCancel: (res, cel) => { + let cancelBackData = res + ";" + JSON.stringify(cel); + } + }, + border: { radius: 50 }, + onComplete: (event) => { + if (event && event.loadingStatus == 0) { + let render_success = JSON.stringify(Date.now()) + } + } + }) +}).width(100).height(100) +``` + #### 复用场景 在aboutToRecycle生命周期清空组件内容;通过watch监听触发图片的加载。 ## 接口说明 @@ -287,44 +316,48 @@ ImageKnifeAnimatorComponent({ ### ImageKnifeOption参数列表 -| 参数名称 | 入参内容 | 功能简介 | -|-----------------------|-------------------------------------------------------|-----------------| -| loadSrc | string、PixelMap、Resource | 主图展示 | -| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) | -| errorholderSrc | PixelMap、Resource | 错误图展示(可选) | -| objectFit | ImageFit | 主图填充效果(可选) | -| placeholderObjectFit | ImageFit | 占位图填充效果(可选) | -| errorholderObjectFit | ImageFit | 错误图填充效果(可选) | -| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) | -| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) | -| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 | -| border | BorderOptions | 边框圆角(可选) | -| priority | taskpool.Priority | 加载优先级(可选) | -| context | common.UIAbilityContext | 上下文(可选) | -| progressListener | (progress: number)=>void | 进度(可选) | -| signature | String | 自定义缓存关键字(可选) | -| headerOption | Array | 设置请求头(可选) | -| transformation | PixelMapTransformation | 图片变换(可选) | -| drawingColorFilter | ColorFilter | drawing.ColorFilter | 图片变换(可选) | -| onComplete | (event:EventImage | undefined) => voi | 颜色滤镜效果(可选) | -| onLoadListener | onLoadStart: () => void、onLoadSuccess: (data: string | PixelMap | undefined) => void、onLoadFailed: (err: string) => void| 监听图片加载成功与失败 | +| 参数名称 | 入参内容 | 功能简介 | +|-----------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| loadSrc | string、PixelMap、Resource | 主图展示 | +| placeholderSrc | PixelMap、Resource | 占位图图展示(可选) | +| errorholderSrc | PixelMap、Resource | 错误图展示(可选) | +| objectFit | ImageFit | 主图填充效果(可选) | +| placeholderObjectFit | ImageFit | 占位图填充效果(可选) | +| errorholderObjectFit | ImageFit | 错误图填充效果(可选) | +| writeCacheStrategy | CacheStrategyType | 写入缓存策略(可选) | +| onlyRetrieveFromCache | boolean | 是否跳过网络和本地请求(可选) | +| customGetImage | (context: Context, src: string | 自定义下载图片(可选) | | Resource | 错误占位图数据源 | +| border | BorderOptions | 边框圆角(可选) | +| priority | taskpool.Priority | 加载优先级(可选) | +| context | common.UIAbilityContext | 上下文(可选) | +| progressListener | (progress: number)=>void | 进度(可选) | +| signature | String | 自定义缓存关键字(可选) | +| headerOption | Array | 设置请求头(可选) | +| transformation | PixelMapTransformation | 图片变换(可选) | +| drawingColorFilter | ColorFilter \| drawing.ColorFilter | 图片变换(可选) | +| onComplete | (event:EventImage \| undefined) => voi | 颜色滤镜效果(可选) | +| onLoadListener | onLoadStart: (call?: ImageKnifeData) => void、onLoadSuccess: (data: string \| PixelMap \| undefined,call?: ImageKnifeData) => void、onLoadFailed: (err: string,errorInfo?: ErrorInfo) => void | 监听图片加载成功与失败 | ### ImageKnife接口 -| 参数名称 | 入参内容 | 功能简介 | -|------------------|-------------------------------------------------------------------------------------------------------|---------------| -| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 | -| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 | -| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 | -| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 | -| addHeader | key: string, value: Object | 全局添加http请求头 | -| setHeaderOptions | Array | 全局设置http请求头 | -| deleteHeader | key: string | 全局删除http请求头 | -| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise | 全局设置自定义下载 | -| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 | -| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 | -| removeMemoryCache| url: string | ImageKnifeOption | 清理指定内存缓存 | -| removeFileCache | url: string | ImageKnifeOption | 清理指定磁盘缓存 | +| 参数名称 | 入参内容 | 功能简介 | +|------------------|-------------------------------------------------------------------------------------------------------|------------------| +| initMemoryCache | newMemoryCache: IMemoryCache | 自定义内存缓存策略 | +| initFileCache | context: Context, size: number, memory: number | 初始化文件缓存数量和大小 | +| preLoadCache | loadSrc: string I ImageKnifeOption | 预加载并返回文件缓存路径 | +| getCacheImage | loadSrc: string, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string) | 从内存或文件缓存中获取资源 | +| addHeader | key: string, value: Object | 全局添加http请求头 | +| setHeaderOptions | Array | 全局设置http请求头 | +| deleteHeader | key: string | 全局删除http请求头 | +| setCustomGetImage | customGetImage?: (context: Context, src: string | PixelMap | Resource) => Promise | 全局设置自定义下载 | +| setEngineKeyImpl | IEngineKey | 全局配置缓存key生成策略 | +| putCacheImage | url: string, pixelMap: PixelMap, cacheType: CacheStrategy = CacheStrategy.Default, signature?: string | 写入内存磁盘缓存 | +| removeMemoryCache| url: string \| ImageKnifeOption | 清理指定内存缓存 | +| removeFileCache | url: string \| ImageKnifeOption | 清理指定磁盘缓存 | +| getCacheUpperLimit | cacheType?: CacheStrategy | 获取指定缓存的上限大小 | +| getCurrentPicturesNum | cacheType?: CacheStrategy | 获取指定缓存的当前缓存图片个数 | +| getCurrentCacheSize | cacheType?: CacheStrategy | 获取指定缓存的当前大小 | + ### 图形变换类型(需要为GPUImage添加依赖项) | 类型 | 相关描述 | diff --git a/library/src/main/ets/ImageKnife.ets b/library/src/main/ets/ImageKnife.ets index 79c9fe6..8381c8f 100644 --- a/library/src/main/ets/ImageKnife.ets +++ b/library/src/main/ets/ImageKnife.ets @@ -327,7 +327,7 @@ export class ImageKnife { * @param cacheType * @returns */ - getCurrentPicturesNum(cacheType: CacheStrategy): number | undefined { + getCurrentPicturesNum(cacheType?: CacheStrategy): number | undefined { if (cacheType == undefined || cacheType == CacheStrategy.Default) { cacheType = CacheStrategy.Memory; } @@ -347,7 +347,7 @@ export class ImageKnife { * @param cacheType * @returns */ - getCurrentCacheSize(cacheType: CacheStrategy): number | undefined { + getCurrentCacheSize(cacheType?: CacheStrategy): number | undefined { if (cacheType == undefined || cacheType == CacheStrategy.Default) { cacheType = CacheStrategy.Memory; }