Flutter图片加载原理与缓存,GitHub已标星16k

本文深入探讨了Flutter中图片加载的过程,包括下载图片、解码图片的步骤。重点解析了`Image`组件的缓存机制,指出图片缓存在内存中,由`ImageCache`管理,并详细阐述了`putIfAbsent`方法的工作原理。此外,文章还提到缓存的key由`ImageProvider`的`obtainKey`方法生成,不同的`ImageProvider`有不同的key生成逻辑。最后,提到了`RawImage`在构建过程中的作用,用于将解码后的图片绘制到屏幕上。
摘要由CSDN通过智能技术生成

));
},
);
if (bytes.lengthInBytes == 0)
throw Exception(‘NetworkImage is an empty file: $resolved’);
// 对图片数据进行解码
return PaintingBinding.instance.instantiateImageCodec(bytes);
} finally {
chunkEvents.close();
}
}

可以看到_loadAsync方法主要做了两件事:

  1. 下载图片。
  2. 对下载的图片数据进行解码。

下载逻辑比较简单:通过HttpClient从网上下载图片,另外下载请求会设置一些自定义的header,开发者可以通过NetworkImageheaders命名参数来传递。

在图片下载完成后调用了PaintingBinding.instance.instantiateImageCodec(bytes)对图片进行解码,值得注意的是instantiateImageCodec(...)也是一个Native API的包装,实际上会调用Flutter engine的instantiateImageCodec方法,源码如下:

String _instantiateImageCodec(Uint8List list, _Callback callback, _ImageInfo imageInfo, int targetWidth, int targetHeight)
native ‘instantiateImageCodec’;

obtainKey(ImageConfiguration)方法

该接口主要是为了配合实现图片缓存,ImageProvider从数据源加载完数据后,会在全局的ImageCache中缓存图片数据,而图片数据缓存是一个Map,而Map的key便是调用此方法的返回值,不同的key代表不同的图片数据缓存。

resolve(ImageConfiguration) 方法

resolve方法是ImageProvider的暴露的给Image的主入口方法,它接受一个ImageConfiguration参数,返回ImageStream,即图片数据流。我们重点看一下resolve执行流程:

ImageStream resolve(ImageConfiguration configuration) {
… //省略无关代码
final ImageStream stream = ImageStream();
T obtainedKey; //
//定义错误处理函数
Future handleError(dynamic exception, StackTrace stack) async {
… //省略无关代码
stream.setCompleter(imageCompleter);
imageCompleter.setError(…);
}

// 创建一个新Zone,主要是为了当发生错误时不会干扰MainZone
final Zone dangerZone = Zone.current.fork(…);

dangerZone.runGuarded(() {
Future key;
// 先验证是否已经有缓存
try {
// 生成缓存key,后面会根据此key来检测是否有缓存
key = obtainKey(configuration);
} catch (error, stackTrace) {
handleError(error, stackTrace);
return;
}
key.then((T key) {
obtainedKey = key;
// 缓存的处理逻辑在这里,记为A,下面详细介绍
final ImageStreamCompleter completer = PaintingBinding.instance
.imageCache.putIfAbsent(key, ()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值