ImageKnife是一款图像加载缓存库,主要功能特性如下:

●支持内存缓存,使用LRUCache算法,对图片数据进行内存缓存。

●支持磁盘缓存,对于下载图片会保存一份至磁盘当中。

●支持进行图片变换:支持图像像素源图片变换效果。

●支持用户配置参数使用:(例如:配置是否开启一级内存缓存,配置磁盘缓存策略,配置仅使用缓存加载数据,配置图片变换效果,配置占位图,配置加载失败占位图等)。

背景说明

早期ImageKnife三方库在实现渲染部分的时候,使用的是image组件来展示图片的。由于image组件其实是一个完整的集加载解析和图片展示的组件,渲染的模式只能通过配置固定参数进行,面对复杂的需求场景,可能会出现扩展性不够的情况。

现在随着时间的推移渲染组件又多了一位重量级选手Canvas组件。可以通过2个组件渲染层的能力对比进行判断渲染层最终交由哪个组件展示。

组件选型,能力对比

首先我们来看看Image组件和Canvas组件对于渲染这一块的支持情况。

ArkUI框架开发-ImageKnife渲染层重构_openHarmony

从上表我们可以看出:

Image组件虽然支持了PixelMap的绘制,但是基本没有绘制控制能力,而且扩展性能力也比较弱,并且渲染过程不可见,也无法对绘制内容进行更多操作。

而Canvas组件属于更加底层的渲染组件,可以完美地控制绘制内容,并且渲染过程可见,符合了开发者对于扩展性要求较高的定制场景。

重构前后能力对比

ArkUI框架开发-ImageKnife渲染层重构_组件化_02

重构完成的内容

1. 使用canvas组件替代Image组件进行渲染展示图片。

2. 所有图像数据在渲染层都转换为PixelMap,方便统一管理和扩展。

3. 所有回调节点,统一抽象成接口,方便后续进行扩展,提高代码可维护性。

4. 所有的回调节点绘制的实现,都采用了责任链模式,提高了自定义绘制扩展能力。

5. 将部分通用方法封装成工厂方法,减少开发者代码量。

6. 通用方法从配置参数剥离,可采用链式调用方式使用这些方法。

7. 为了支持列表ImageKnifeOption参数使用@LinkObject修饰,同时ImageKnifeOption类型被@Observed修饰继承,不可被继承。

重构中比较重要的点

点1:回调接口抽象为IDrawLifeCycle接口

渲染绘制是主线程才能操作。因此我们可以对渲染顺序进行了梳理,大致流程:展示占位图->展示网络加载进度->展示缩略图->展示主图->展示重试图层->展示失败占位图

ArkUI框架开发-ImageKnife渲染层重构_组件化_03

这里每个蓝色的小方格都代表着一个数据返回的回调接口,我们需要在这个回调接口,处理接下来内容渲染的展示操作。因为每个回调的流程是固定的,有点像生命周期的流程。所以我这边抽象成接口IDrawLifeCycle绘制生命周期进行表达。这其实也是为了后面扩展做了准备。

点2:绘制实现采用责任链模式

我们支持了用户配置自定义绘制和全局配置自定义绘制的能力。采用了责任链模式实现,用户参数设置->全局参数设置->自定义组件内部设置。这样设计的好处就是保留了用户扩展的能力,用户可以参与自定义绘制。

ArkUI框架开发-ImageKnife渲染层重构_openHarmony_04

点3:提供了ImageKnifeDrawFactory工厂类

在开发者需要进行自定义绘制时,必须实现IDrawLifeCycle的6个接口。为了简化开发者操作,这里提供了ImageKnifeDrawFactory工厂类。

ImageKnifeDrawFactory里面封装了圆角、椭圆、百分比下载等实现,简化用户操作。当然更多的需求,可以参考该工厂类自行扩展实现。

这里我们提供简单的场景示例:

场景1:一句代码,加个圆角效果

代码如下:

import {ImageKnifeComponent} from '@ohos/imageknife'
import {ImageKnifeOption} from '@ohos/imageknife'
import {ImageKnifeDrawFactory} from '@ohos/imageknife'
@Entry
@Component
struct Index {
  @State imageKnifeOption1: ImageKnifeOption =
    { // 加载一张本地的png资源(必选)
      loadSrc: $r('app.media.pngSample'),
      // 主图的展示模式是 缩放至适合组件大小,并且在组件底部绘制
      mainScaleType: ScaleType.FIT_END,
      // 占位图使用本地资源icon_loading(可选)
      placeholderSrc: $r('app.media.icon_loading'),
      // 失败占位图使用本地资源icon_failed(可选)
      errorholderSrc: $r('app.media.icon_failed'),
      // 绘制圆角30,边框5,边框"#ff00ff".用户自定义绘制(可选)
      drawLifeCycle:ImageKnifeDrawFactory.createRoundLifeCycle(5,"#ff00ff",30)
    };
  build() {
    Scroll() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
        ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
          .width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
          .height(300)
      }
    }
    .width('100%')
    .height('100%')
  }
}

ArkUI框架开发-ImageKnife渲染层重构_鸿蒙开发_05

场景2:全局配置网络下载百分比效果展示

仅需一句代码所有网络图片加载都能新增网络下载百分比效果展示。代码如下:

import AbilityStage from '@ohos.application.Ability'
import { ImageKnife,ImageKnifeDrawFactory} from '@ohos/imageknife'

export default class EntryAbility extends Ability {
    onCreate(want,launchParam) {
        globalThis.ImageKnife = ImageKnife.with(this.context);
        // 全局配置网络加载进度条
        globalThis.ImageKnife.setDefaultLifeCycle(ImageKnifeDrawFactory.createProgressLifeCycle("#10a5ff", 0.5))
    }
}

这里大家可能会问,为什么会将这个IDrawLifeCycle放在EntryAbility里面实现?

这是因为网络下载百分比进度很多时候都是全局通用,如果有需要全局配置的自定义展示方案。推荐在EntryAbility里面,往ImageKnife的setDefaultLifeCycle函数中注入,即可将ImageKnifeComponent中的默认绘制方案替换。

在这里我们实现的效果如下图所示。

ArkUI框架开发-ImageKnife渲染层重构_组件化_06

点4:通用属性方法和属性已经支持链式调用

比如下面的代码的宽高已经不用设置在ImageKnifeOption对象中了,直接在自定义组件下方链式调用设置即可。

import {ImageKnifeComponent,ImageKnifeOption,ImageKnifeDrawFactory} from '@ohos/imageknife'
@Entry
@Component
struct Index {
  @State imageKnifeOption1: ImageKnifeOption =
    { // 加载一张本地的png资源(必选)
      loadSrc: $r('app.media.pngSample'),
    };
  build() {
    Scroll() {
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
        ImageKnifeComponent({ imageKnifeOption: this.imageKnifeOption1 })
          .width(300) // 自定义组件已支持设置通用属性和事件,这里宽高设置放在链式调用中完成
          .height(300)
      }
    }
    .width('100%')
    .height('100%')
  }
}

点5:如何在列表使用

支持列表使用图片加载,只需要维护一个@State options:Array = []

对象即可

import {ImageKnifeOption,ImageKnifeComponent} from '@ohos/imageknife'
@Entry
@Component
struct BasicTestFeatureAbilityPage {
  urls=[
   "http://e.hiphotos.baidu.com/image/pic/item/a1ec08fa513d2697e542494057fbb2fb4316d81e.jpg",
   "http://c.hiphotos.baidu.com/image/pic/item/30adcbef76094b36de8a2fe5a1cc7cd98d109d99.jpg",
   "http://h.hiphotos.baidu.com/image/pic/item/7c1ed21b0ef41bd5f2c2a9e953da81cb39db3d1d.jpg",
   "http://g.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d5277fd5d0628535e5dd6f4a.jpg",
   "http://e.hiphotos.baidu.com/image/pic/item/4e4a20a4462309f7e41f5cfe760e0cf3d6cad6ee.jpg",
 ]
  @State options:Array<ImageKnifeOption> = []
  aboutToAppear(){
    this.options =  this.urls.map((url)=>{
      return {
        loadSrc:url
      }
    })
    console.log('this.options length ='+this.options.length)
  }
  build() {
    Stack({ alignContent: Alignment.TopStart }) {
      Column() {
        List({ space: 20, initialIndex: 0 }) {
          ForEach(this.options, (item) => {
            ListItem() {
              ImageKnifeComponent({imageKnifeOption:item}).width(300).height(300)
            }
          }, item => item.loadSrc)
        }
        .listDirection(Axis.Vertical) // 排列方向
        .divider({ strokeWidth: 2, color: 0xFFFFFF, startMargin: 20, endMargin: 20 }) // 每行之间的分界线
        .edgeEffect(EdgeEffect.None) // 滑动到边缘无效果
        .chainAnimation(false) // 联动特效关闭
      }.width('100%')
    }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 })
  }
}

渲染层重构的总结

综上可知,此次重构渲染层,一共新增了6个基础能力,适配了IDE最新版特性自定义组件可链式调用通用属性和方法,并且采用适合的设计模式保留了自定义组件绘制部分的拓展能力。展示了部分常用场景下使用代码的方式,帮助开发者更快上手开发。

最后在OpenHarmony不断推陈出新之际,三方库ImageKnife也应该激流勇进,不断地提升组件的实用性和适用性,为开发者创造一个良好的开发体验。

经常有很多小伙伴抱怨说:不知道学习鸿蒙开发哪些技术?不知道需要重点掌握哪些鸿蒙应用开发知识点?

为了能够帮助到大家能够有规划的学习,这里特别整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(ArkTS、ArkUI开发组件、Stage模型、多端部署、分布式应用开发、WebGL、元服务、OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植等等)鸿蒙(HarmonyOS NEXT)技术知识点。

ArkUI框架开发-ImageKnife渲染层重构_组件化_07

《鸿蒙 (Harmony OS)开发学习手册》(共计892页)

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

ArkUI框架开发-ImageKnife渲染层重构_openHarmony_08

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

ArkUI框架开发-ImageKnife渲染层重构_移动开发_09

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

ArkUI框架开发-ImageKnife渲染层重构_移动开发_10

鸿蒙开发面试真题(含参考答案)

ArkUI框架开发-ImageKnife渲染层重构_openHarmony_11

OpenHarmony 开发环境搭建

ArkUI框架开发-ImageKnife渲染层重构_移动开发_12

《OpenHarmony源码解析》

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

ArkUI框架开发-ImageKnife渲染层重构_ArkUI_13

OpenHarmony 设备开发学习手册

ArkUI框架开发-ImageKnife渲染层重构_ArkUI_14