ub3lal 4 weken geleden
bovenliggende
commit
d34def80ba
3 gewijzigde bestanden met toevoegingen van 42 en 39 verwijderingen
  1. 1 1
      lib/src/CashedNetworkImageWidget.dart
  2. 40 37
      lib/src/http_request.dart
  3. 1 1
      pubspec.yaml

+ 1 - 1
lib/src/CashedNetworkImageWidget.dart

@@ -102,7 +102,7 @@ class CachedNetworkImageWidgetState extends State<CachedNetworkImageWidget>
 
           if (state is CashedImageGetState) {
             ImageProvider imageProvider = MemoryImage(state.bytes);
-            return widget.imageBuilder(context, imageProvider!);
+            return widget.imageBuilder(context, imageProvider);
           }
           return SizedBox(
             width: widget.width,

+ 40 - 37
lib/src/http_request.dart

@@ -7,6 +7,7 @@ class HttpGetImage {
   final String url;
   final int count;
   final Map<String, String>? httpHeaders;
+
   HttpGetImage({
     required this.url,
     required this.count,
@@ -16,77 +17,79 @@ class HttpGetImage {
   Future<Uint8List> getDataObjectIsolate() async {
     final ReceivePort receivePort = ReceivePort();
 
-    var data = {'sendPort': receivePort.sendPort, 'url': url, 'count': count};
-
-    if (httpHeaders != null) {
-      data = {
-        'sendPort': receivePort.sendPort,
-        'url': url,
-        'headers': httpHeaders!,
-        'count': count,
-      };
-    }
-
-    final Isolate isolate = await Isolate.spawn(_isolateFetchVideo, data);
+    final data = {
+      'sendPort': receivePort.sendPort,
+      'url': url,
+      'count': count,
+      if (httpHeaders != null) 'headers': httpHeaders!,
+    };
 
+    // Чтобы избежать утечек памяти, используем try-finally для закрытия порта
+    Isolate? isolate;
     try {
+      isolate = await Isolate.spawn(_isolateFetchVideo, data);
       final dynamic result = await receivePort.first;
-      isolate.kill();
 
       if (result is Uint8List) {
         return result;
       } else {
-        throw Exception();
+        throw Exception("Failed to load image bytes or received null");
       }
-    } catch (e) {
-      isolate.kill();
-      throw Exception();
     } finally {
+      isolate?.kill(priority: Isolate.immediate);
       receivePort.close();
     }
   }
 
-  Future<void> _isolateFetchVideo(Map<String, dynamic> message) async {
+  // Обязательно делаем функцию STATIC, чтобы изолят мог её запустить без контекста класса
+  static Future<void> _isolateFetchVideo(Map<String, dynamic> message) async {
     final SendPort sendPort = message['sendPort'];
     final String url = message['url'];
-    int count = message['count'];
-    Map<String, String>? headers = message.containsKey("headers")
-        ? message['headers']
-        : null;
+    final int count = message['count'];
+    final Map<String, String>? headers =
+        message['headers'] as Map<String, String>?;
 
     int time = 10;
-    late http.Response response;
 
-    do {
-      if (time > count) {
-        sendPort.send(null);
-        break;
-      }
+    // Заменяем do-while на контролируемый цикл по попыткам
+    while (time <= count) {
       try {
-        response = await http
+        final response = await http
             .get(Uri.parse(url), headers: headers)
             .timeout(Duration(seconds: time));
 
         if (response.statusCode == 200) {
-          try {
-            if (response.body.isNotEmpty) {
+          if (response.body.isNotEmpty) {
+            try {
               final data = jsonDecode(response.body);
-
               if (data is Map) {
+                // Если пришел JSON вместо сырых байт картинки
                 sendPort.send(null);
-                break;
+                return;
               }
+            } catch (_) {
+              // Если это не JSON (значит, скорее всего, чистые байты картинки) — всё отлично
             }
-          } catch (e) {}
+          }
 
           sendPort.send(response.bodyBytes);
-          break;
+          return; // Успешно выходим из функции
         }
+
+        // Если код не 200 (например 500), увеличиваем таймаут и пробуем снова
         time++;
       } catch (e) {
-        sendPort.send(null);
+        // Если поймали TimeoutException или SocketException:
+        // В дебаге это частая история. Увеличиваем время и идем на следующую итерацию.
+        time++;
+        if (time > count) {
+          sendPort.send(null);
+          return;
+        }
       }
-    } while (response.statusCode != 200);
+    }
+
+    // Если превысили лимит count и ничего не вернули
     sendPort.send(null);
   }
 }

+ 1 - 1
pubspec.yaml

@@ -1,6 +1,6 @@
 name: network_image_cached
 description: "Network image"
-version: 0.0.6
+version: 0.0.7
 homepage:
 
 environment: