!223 【ImageKnife】加载图片支持自定义网络栈补充XTS用例以及优化按钮重复点击问题

Merge pull request !223 from zhanghanyong/master
This commit is contained in:
openharmony_ci 2024-04-29 01:41:40 +00:00 committed by Gitee
commit bb57dc0f51
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 158 additions and 10 deletions

View File

@ -108,6 +108,40 @@ imageKnifeOption = {
### 6.自定义请求头规格 ### 6.自定义请求头规格
设置全局header并且设置request的header时当key不同时全局和request并行当key相同时request的header覆盖全局的header 设置全局header并且设置request的header时当key不同时全局和request并行当key相同时request的header覆盖全局的header
### 7.自定义网络栈加载图片
7.1 自定义网络栈加载单个图片在imageKnifeNextOption中添加customGetImage标签然后完善custom函数的逻辑即可
```
ImageKnifeNextComponent({
imageKnifeNextOption: {
loadSrc: 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg',
placeholderSrc: $r('app.media.icon_loading'),
errorholderSrc: $r('app.media.icon_failed'),
customGetImage: custom
}
}).width(100).height(100)
// 自定义实现图片获取方法,如自定义网络下载
@Concurrent
async function custom(context: Context, src: string): Promise<ArrayBuffer | undefined> {
let result: DataFetchResult = new DataFetchResult();
result.data = arraybuffer; //此处替换成自己网络获取的ArrayBuffer的逻辑
return result;
}
```
7.2 自定义网络栈加载全部图片
```
1.先执行ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient()); 替换网络栈
2.在CustomDataFetchClient这个类中也通过下面的逻辑替换成自己网络获取的ArrayBuffer的逻辑
let result: DataFetchResult = new DataFetchResult();
result.data = arraybuffer; //此处替换成自己网络获取的ArrayBuffer的逻辑
return result;
```
7.3 取消自定义网络栈加载全部图片
```
如果用户执行了自定义网络加载全部图片,后面又不想自定义网络栈加载全部图片了,可以通过下面的方式恢复
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient());
```
## 进阶使用 ## 进阶使用
如果简单的加载一张图像无法满足需求我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。 如果简单的加载一张图像无法满足需求我们可以看看ImageKnifeOption这个类提供了哪些扩展能力。
@ -143,6 +177,7 @@ imageKnifeOption = {
| imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置设置为false时imageSmoothingQuality失效 | | imageSmoothingEnabled | boolean | 抗锯齿是否开启属性配置设置为false时imageSmoothingQuality失效 |
| imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 | | imageSmoothingQuality | AntiAliasing | 抗锯齿属性配置 |
| autoPlay | boolean | GIF播放暂停控制可选 | | autoPlay | boolean | GIF播放暂停控制可选 |
| customGetImage | (Context, string) | 设置是否使用应用自定义的方式加载图片(可选) |
其他参数只需要在ImageKnifeOption对象上按需添加即可。 其他参数只需要在ImageKnifeOption对象上按需添加即可。
@ -537,6 +572,7 @@ HSP场景适配:
- storageTestDiskLruCache.ets # 磁盘缓存测试 - storageTestDiskLruCache.ets # 磁盘缓存测试
- storageTestLruCache.ets # 内存缓存测试 - storageTestLruCache.ets # 内存缓存测试
- testAllCacheInfoPage.ets # 所有缓存信息获取测试 - testAllCacheInfoPage.ets # 所有缓存信息获取测试
- testCustomDataFetchClientWithPage # 测试图片下载使用自定义的网络栈
- testImageKnifeAutoHeightPage.ets # 图片高度自适应测试 - testImageKnifeAutoHeightPage.ets # 图片高度自适应测试
- testImageKnifeAutoWidthPage.ets # 图片宽度自适应测试 - testImageKnifeAutoWidthPage.ets # 图片宽度自适应测试
- testImageKnifeAutoPage.ets # 图片宽高自适应测试 - testImageKnifeAutoPage.ets # 图片宽高自适应测试

View File

@ -79,6 +79,8 @@ struct TestCustomDataFetchClientWithPage {
@State isSingleImageVisible: boolean = true; @State isSingleImageVisible: boolean = true;
@State isAllImageVisible: boolean = false; @State isAllImageVisible: boolean = false;
@State isCustom: boolean = false; @State isCustom: boolean = false;
private isAllImageAdded: boolean = false;
private isCancelImageAdded: boolean = false;
private data: Array<string> = [ private data: Array<string> = [
"http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg", "http://img2.xkhouse.com/bbs/hfhouse/data/attachment/forum/corebbs/2009-11/2009113011534566298.jpg",
"http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg" "http://a.hiphotos.baidu.com/image/pic/item/e824b899a9014c087eb617650e7b02087af4f464.jpg"
@ -107,7 +109,6 @@ struct TestCustomDataFetchClientWithPage {
LogUtil.log('TestCustomDataFetch click single.'); LogUtil.log('TestCustomDataFetch click single.');
this.isSingleImageVisible = true; this.isSingleImageVisible = true;
this.isAllImageVisible = false; this.isAllImageVisible = false;
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient());
this.singleImageKnifeOption = { this.singleImageKnifeOption = {
loadSrc: 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg', loadSrc: 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg',
@ -122,8 +123,10 @@ struct TestCustomDataFetchClientWithPage {
this.isAllImageVisible = true; this.isAllImageVisible = true;
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient()); ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new CustomDataFetchClient());
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.addData) if (!this.isAllImageAdded) {
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.addData);
this.isAllImageAdded = true;
}
}) })
Button("取消自定义全部图片").margin(16).onClick(() => { Button("取消自定义全部图片").margin(16).onClick(() => {
@ -132,7 +135,10 @@ struct TestCustomDataFetchClientWithPage {
this.isAllImageVisible = true; this.isAllImageVisible = true;
ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new DownloadClient()); ImageKnifeGlobal.getInstance().getImageKnife()?.replaceDataFetch(new DownloadClient());
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.cancelData) if (!this.isCancelImageAdded) {
this.hotCommendList.addData(this.hotCommendList.totalCount(), this.cancelData);
this.isCancelImageAdded = true;
}
}) })
} }

View File

@ -14,6 +14,7 @@
*/ */
import abilityTest from './Ability.test' import abilityTest from './Ability.test'
import lruCacheTest from './lrucache.test' import lruCacheTest from './lrucache.test'
import CustomDataFetchClientTest from './customdatafetchclient.test'
import LogUtilTest from './logutil.test' import LogUtilTest from './logutil.test'
import Transfrom from './transfrom.test' import Transfrom from './transfrom.test'
import RequestOptionTest from './requestoption.test' import RequestOptionTest from './requestoption.test'
@ -32,4 +33,5 @@ export default function testsuite() {
ImageKnifeTest(); ImageKnifeTest();
SendableDataTest(); SendableDataTest();
DefaultJobQueueTest(); DefaultJobQueueTest();
CustomDataFetchClientTest();
} }

View File

@ -0,0 +1,106 @@
/*
* 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 { DownloadClient } from '@ohos/imageknife/src/main/ets/components/imageknife/networkmanage/DownloadClient';
import common from '@ohos.app.ability.common';
import { GlobalContext } from '../testability/GlobalContext';
import { CustomDataFetchClient, DataFetchResult, ImageKnifeGlobal, RequestOption } from '@ohos/imageknife';
const BASE_COUNT: number = 2000;
export default function CustomDataFetchClientTest() {
describe('CustomDataFetchClientTest', () => {
// 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('TestIsLocalLoadSrc', 0, () => {
let path = 'invalid path';
let client = new DownloadClient()
expect(client.isLocalLoadSrc(undefined, path)).assertFalse();
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
if (context != undefined) {
let loadSrc1 = (context as common.UIAbilityContext).filesDir + 'a.jpg';
let loadSrc2 = (context as common.UIAbilityContext).cacheDir + 'b.jpg';
expect(client.isLocalLoadSrc(context, loadSrc1)).assertTrue();
expect(client.isLocalLoadSrc(context, loadSrc2)).assertTrue();
}
})
it('TestLoadData', 1, async () => {
let client = new CustomDataFetchClient();
let request = new RequestOption();
request.loadSrc = $r('app.media.icon');
let error = (await client.loadData(request) as DataFetchResult).error as String;
expect(error).assertEqual('CustomDataFetchClient request or loadSrc error.');
})
it('TestLoadData_customGetImage', 2, async () => {
let client = new CustomDataFetchClient();
let request = new RequestOption();
request.loadSrc = 'http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg';
request.customGetImage = (context: Context, src: string) => {
// 这里是模拟的customGetImage逻辑
return Promise.resolve(new DataFetchResult());
}
console.log('LXH', 'TestLoadData 2 --1 customGetImage is undefined ?' + (request.customGetImage == undefined));
let context: object | undefined = GlobalContext.getInstance().getObject("hapContext");
let result = await client.loadData(request);
if (context != undefined) {
console.log('LXH', 'TestLoadData 2 --2');
expect(typeof result)
.assertEqual(typeof (await request?.customGetImage(context as common.UIAbilityContext, request.loadSrc)));
}
})
it('TestLoadData_combineArrayBuffers', 3, () => {
// 创建几个ArrayBuffer作为测试数据
const arrayBuffer1 = new ArrayBuffer(4);
const uint8Array1 = new Uint8Array(arrayBuffer1);
uint8Array1[0] = 1;
uint8Array1[1] = 2;
uint8Array1[2] = 3;
uint8Array1[3] = 4;
const arrayBuffer2 = new ArrayBuffer(2);
const uint8Array2 = new Uint8Array(arrayBuffer2);
uint8Array2[0] = 5;
uint8Array2[1] = 6;
let client = new CustomDataFetchClient();
const combinedArrayBuffer = client.combineArrayBuffers([arrayBuffer1, arrayBuffer2]);
expect(combinedArrayBuffer.byteLength).assertEqual(6);
const combinedUint8Array = new Uint8Array(combinedArrayBuffer);
for (let i = 0; i < 4; i++) {
expect(combinedUint8Array[i]).assertEqual(uint8Array1[i]);
}
for (let i = 0; i < 2; i++) {
expect(combinedUint8Array[i + 4]).assertEqual(uint8Array2[i]);
}
});
})
}

View File

@ -29,11 +29,6 @@ export class CustomDataFetchClient implements IDataFetch {
result.error = 'CustomDataFetchClient request or loadSrc error.'; result.error = 'CustomDataFetchClient request or loadSrc error.';
return result; return result;
} }
// 自定义单个图片的网络栈
if (request.customGetImage) {
return await request.customGetImage(ImageKnifeGlobal.getInstance()
.getHapContext() as common.UIAbilityContext, request.loadSrc);
}
// 所有图片的网络栈 // 所有图片的网络栈
try { try {
let httpRequest = http.createHttp() let httpRequest = http.createHttp()

View File

@ -35,7 +35,10 @@ export class DownloadClient implements IDataFetch {
async loadData(request: RequestOption): Promise<DataFetchResult> { async loadData(request: RequestOption): Promise<DataFetchResult> {
if (typeof request.loadSrc == 'string') { if (typeof request.loadSrc == 'string') {
if (this.isLocalLoadSrc(ImageKnifeGlobal.getInstance().getHapContext(), request.loadSrc)) { if (request.customGetImage) {
return await request.customGetImage(ImageKnifeGlobal.getInstance()
.getHapContext() as common.UIAbilityContext, request.loadSrc);
} else if (this.isLocalLoadSrc(ImageKnifeGlobal.getInstance().getHapContext(), request.loadSrc)) {
// 本地沙盒 // 本地沙盒
return this.localFileClient.loadData(request) return this.localFileClient.loadData(request)
} else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) { } else if (request.loadSrc.startsWith('datashare://') || request.loadSrc.startsWith('file://')) {