CachedNetworkImage 在加载某些https网站的图像时会出现类似这样的错误:
I/flutter: The following HandshakeException was thrown resolving an image codec: Handshake error in client (OS Error: CERTIFICATE_VERIFY_FAILED: self signed certificate(handshake.cc:352)) 08-05 16:27:56.673 13676-13696/com.example.flutter_module.host I/flutter: When the exception was thrown, this was the stack: 08-05 16:27:56.688 13676-13696/com.example.flutter_module.host I/flutter: #0 NetworkImage._loadAsync (package:flutter/src/painting/image_provider.dart:490:39)
这就是证书问题了。
CachedNetworkImage 提供了一个参数 cacheManager , 一般我们都不会指定,那么它会使用 DefaultCacheManager 。DefaultCacheManager 中会使用一个 FileService 来下载图像。那么,我们只需要做一个 CacheManager ,并自定义一个 FileService 就可以解决此问题了。具体代码如下:
import 'dart:async'; import 'package:flutter_cache_manager/flutter_cache_manager.dart'; import 'package:http/http.dart' as http; import 'dart:io'; /// 缓存管理 class EsoImageCacheManager extends CacheManager { static const key = 'libEsoCachedImageData'; static EsoImageCacheManager _instance; factory EsoImageCacheManager() { _instance ??= EsoImageCacheManager._(); return _instance; } EsoImageCacheManager._() : super(Config(key, fileService: EsoHttpFileService())); } class EsoHttpFileService extends FileService { HttpClient _httpClient; EsoHttpFileService({HttpClient httpClient}) { _httpClient = httpClient ?? HttpClient(); _httpClient.badCertificateCallback = (cert, host, port) => true; } @override Future<FileServiceResponse> get(String url, {Map<String, String> headers = const {}}) async { final Uri resolved = Uri.base.resolve(url); final HttpClientRequest req = await _httpClient.getUrl(resolved); headers?.forEach((key, value) { req.headers.add(key, value); }); final HttpClientResponse httpResponse = await req.close(); final http.StreamedResponse _response = http.StreamedResponse( httpResponse.timeout(Duration(seconds: 60)), httpResponse.statusCode, contentLength: httpResponse.contentLength, reasonPhrase: httpResponse.reasonPhrase, isRedirect: httpResponse.isRedirect, ); return HttpGetResponse(_response); } }
使用方法:
CachedNetworkImage(
imageUrl: url,
fit: BoxFit.cover,
cacheManager: EsoImageCacheManager()
)
经测试,问题解决。