Flutter中使用NetworkImage加载网络图片缓存问题学习实践

发布于:2025-03-14 ⋅ 阅读:(15) ⋅ 点赞:(0)
Flutter中默认的NetworkImage会有缓存机制,如果图片的url不变化,但是url的图片已经发生变化,NetworkImage不会下载新的图片

deepseek是这么解决问题的,但是在鸿蒙上禁用缓存无效

在Flutter中,NetworkImage默认会使用缓存机制来优化性能。如果你想禁用缓存,可以通过以下几种方式实现:

1. 使用 NetworkImage 的 headers 参数

你可以通过设置 headers 参数来禁用缓存。例如,添加 Cache-Control 头来禁用缓存:

dart

复制

Image(
  image: NetworkImage(
    'https://example.com/image.png',
    headers: {
      'Cache-Control': 'no-cache',
    },
  ),
)

2. 使用 CachedNetworkImage 并禁用缓存

如果你使用的是 cached_network_image 包,可以通过设置 cacheKey 来避免缓存:

dart

复制

CachedNetworkImage(
  imageUrl: 'https://example.com/image.png',
  cacheKey: DateTime.now().toString(), // 使用当前时间戳作为缓存键
)

3. 使用 HttpClient 手动下载图片

你可以使用 HttpClient 手动下载图片,并禁用缓存:

dart

import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';

class NoCacheNetworkImage extends ImageProvider<NoCacheNetworkImage> {
  final String url;

  NoCacheNetworkImage(this.url);

  @override
  Future<NoCacheNetworkImage> obtainKey(ImageConfiguration configuration) {
    return SynchronousFuture<NoCacheNetworkImage>(this);
  }

  @override
  ImageStreamCompleter load(NoCacheNetworkImage key, DecoderCallback decode) {
    return MultiFrameImageStreamCompleter(
      codec: _loadAsync(key),
      scale: 1.0,
    );
  }

  Future<ui.Codec> _loadAsync(NoCacheNetworkImage key) async {
    final HttpClient client = HttpClient();
    final HttpClientRequest request = await client.getUrl(Uri.parse(key.url));
    request.headers.add('Cache-Control', 'no-cache');
    final HttpClientResponse response = await request.close();
    final Uint8List bytes = await consolidateHttpClientResponseBytes(response);
    return await ui.instantiateImageCodec(bytes);
  }
}

// 使用
Image(
  image: NoCacheNetworkImage('https://example.com/image.png'),
)

4. 使用 FadeInImage 并禁用缓存

你可以使用 FadeInImage 并结合 NetworkImage 的 headers 参数来禁用缓存:

dart

复制

FadeInImage(
  image: NetworkImage(
    'https://example.com/image.png',
    headers: {
      'Cache-Control': 'no-cache',
    },
  ),
  placeholder: MemoryImage(kTransparentImage),
)

5. 使用 Image.network 并禁用缓存

你也可以直接在 Image.network 中使用 headers 参数:

dart

复制

Image.network(
  'https://example.com/image.png',
  headers: {
    'Cache-Control': 'no-cache',
  },
)

总结

以上方法都可以帮助你禁用 NetworkImage 的缓存机制。选择哪种方式取决于你的具体需求和应用场景。如果你只是简单地想禁用缓存,使用 headers 参数是最直接的方式。如果你需要更复杂的控制,可以考虑手动下载图片或使用 CachedNetworkImage

但是 headers: { 'Cache-Control': 'no-cache', }, 在纯鸿蒙系统上无效,还是NetworkImage,FadeInImage,Image.network 会加载缓存。

实践测试如下:

1. 使用 HttpClient手动下载图片
   使用 HttpClient 添加  request.headers.add('Cache-Control', 'no-cache'); 
实现不实用缓存机制,缺点:加载图片比较慢.

 解决NetworkImage缓存机制的办法: 在url后面添加时间戳参数,每次请求的url都不同, eg:
 //String iconUrl = "$resUrl${servicelist.id}.png?timestamp=${DateTime.now().millisecondsSinceEpoch}";