1+ import 'dart:io' ;
2+ import 'dart:typed_data' ;
3+
4+ import 'package:flutter/foundation.dart' ;
5+ import 'package:flutter/material.dart' ;
6+ import 'dart:ui' as ui show Codec;
7+
8+ import 'package:flutter_cache_manager/flutter_cache_manager.dart' ;
9+
10+ /**
11+ * Created by guoshuyu
12+ * on 2019/4/13.
13+ */
14+ class NetworkCacheImage extends ImageProvider <NetworkCacheImage > {
15+ /// Creates an object that fetches the image at the given URL.
16+ ///
17+ /// The arguments must not be null.
18+ const NetworkCacheImage (this .url, { this .scale = 1.0 , this .headers })
19+ : assert (url != null ),
20+ assert (scale != null );
21+
22+ /// The URL from which the image will be fetched.
23+ final String url;
24+
25+ /// The scale to place in the [ImageInfo] object of the image.
26+ final double scale;
27+
28+ /// The HTTP headers that will be used with [HttpClient.get] to fetch image from network.
29+ final Map <String , String > headers;
30+
31+ @override
32+ Future <NetworkCacheImage > obtainKey (ImageConfiguration configuration) {
33+ return SynchronousFuture <NetworkCacheImage >(this );
34+ }
35+
36+ @override
37+ ImageStreamCompleter load (NetworkCacheImage key) {
38+ return MultiFrameImageStreamCompleter (
39+ codec: _loadAsync (key),
40+ scale: key.scale,
41+ informationCollector: (StringBuffer information) {
42+ information.writeln ('Image provider: $this ' );
43+ information.write ('Image key: $key ' );
44+ },
45+ );
46+ }
47+
48+ static final HttpClient _httpClient = HttpClient ();
49+
50+ Future <ui.Codec > _loadAsync (NetworkCacheImage key) async {
51+ assert (key == this );
52+
53+ /// add this start
54+ /// flutter_cache_manager DefaultCacheManager
55+ final fileInfo = await DefaultCacheManager ().getFileFromCache (key.url);
56+ if (fileInfo != null && fileInfo.file != null ) {
57+ final Uint8List cacheBytes = await fileInfo.file.readAsBytes ();
58+ if (cacheBytes != null ) {
59+ return PaintingBinding .instance.instantiateImageCodec (cacheBytes);
60+ }
61+ }
62+ /// add this end
63+
64+ final Uri resolved = Uri .base .resolve (key.url);
65+ final HttpClientRequest request = await _httpClient.getUrl (resolved);
66+ headers? .forEach ((String name, String value) {
67+ request.headers.add (name, value);
68+ });
69+ final HttpClientResponse response = await request.close ();
70+ if (response.statusCode != HttpStatus .ok)
71+ throw Exception ('HTTP request failed, statusCode: ${response ?.statusCode }, $resolved ' );
72+
73+ final Uint8List bytes = await consolidateHttpClientResponseBytes (response);
74+ if (bytes.lengthInBytes == 0 )
75+ throw Exception ('NetworkCacheImage is an empty file: $resolved ' );
76+
77+ /// add this start
78+ await DefaultCacheManager ().putFile (key.url, bytes);
79+ /// add this edn
80+
81+ return PaintingBinding .instance.instantiateImageCodec (bytes);
82+ }
83+
84+ @override
85+ bool operator == (dynamic other) {
86+ if (other.runtimeType != runtimeType)
87+ return false ;
88+ final NetworkCacheImage typedOther = other;
89+ return url == typedOther.url
90+ && scale == typedOther.scale;
91+ }
92+
93+ @override
94+ int get hashCode => hashValues (url, scale);
95+
96+ @override
97+ String toString () => '$runtimeType ("$url ", scale: $scale )' ;
98+ }
0 commit comments