|
@@ -6,14 +6,37 @@ import 'package:http/http.dart' as http;
|
|
|
class HttpGetImage {
|
|
class HttpGetImage {
|
|
|
final String url;
|
|
final String url;
|
|
|
final int count;
|
|
final int count;
|
|
|
|
|
+ final bool isDebug;
|
|
|
final Map<String, String>? httpHeaders;
|
|
final Map<String, String>? httpHeaders;
|
|
|
|
|
|
|
|
HttpGetImage({
|
|
HttpGetImage({
|
|
|
required this.url,
|
|
required this.url,
|
|
|
required this.count,
|
|
required this.count,
|
|
|
|
|
+ required this.isDebug,
|
|
|
required this.httpHeaders,
|
|
required this.httpHeaders,
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ // Единая точка входа: в дебаге бьём запрос напрямую, в релизе — через изолят
|
|
|
|
|
+ Future<Uint8List> getData() {
|
|
|
|
|
+ if (isDebug) {
|
|
|
|
|
+ return _getDataDirect();
|
|
|
|
|
+ }
|
|
|
|
|
+ return getDataObjectIsolate();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ Future<Uint8List> _getDataDirect() async {
|
|
|
|
|
+ final Uint8List? result = await _fetchWithRetry(
|
|
|
|
|
+ url: url,
|
|
|
|
|
+ count: count,
|
|
|
|
|
+ headers: httpHeaders,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ if (result != null) {
|
|
|
|
|
+ return result;
|
|
|
|
|
+ }
|
|
|
|
|
+ throw Exception("Failed to load image bytes or received null");
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
Future<Uint8List> getDataObjectIsolate() async {
|
|
Future<Uint8List> getDataObjectIsolate() async {
|
|
|
final ReceivePort receivePort = ReceivePort();
|
|
final ReceivePort receivePort = ReceivePort();
|
|
|
|
|
|
|
@@ -49,6 +72,21 @@ class HttpGetImage {
|
|
|
final Map<String, String>? headers =
|
|
final Map<String, String>? headers =
|
|
|
message['headers'] as Map<String, String>?;
|
|
message['headers'] as Map<String, String>?;
|
|
|
|
|
|
|
|
|
|
+ final Uint8List? result = await _fetchWithRetry(
|
|
|
|
|
+ url: url,
|
|
|
|
|
+ count: count,
|
|
|
|
|
+ headers: headers,
|
|
|
|
|
+ );
|
|
|
|
|
+
|
|
|
|
|
+ sendPort.send(result);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Общая логика ретраев: используется и в изоляте, и при прямом вызове в дебаге
|
|
|
|
|
+ static Future<Uint8List?> _fetchWithRetry({
|
|
|
|
|
+ required String url,
|
|
|
|
|
+ required int count,
|
|
|
|
|
+ required Map<String, String>? headers,
|
|
|
|
|
+ }) async {
|
|
|
int time = 10;
|
|
int time = 10;
|
|
|
|
|
|
|
|
// Заменяем do-while на контролируемый цикл по попыткам
|
|
// Заменяем do-while на контролируемый цикл по попыткам
|
|
@@ -64,16 +102,14 @@ class HttpGetImage {
|
|
|
final data = jsonDecode(response.body);
|
|
final data = jsonDecode(response.body);
|
|
|
if (data is Map) {
|
|
if (data is Map) {
|
|
|
// Если пришел JSON вместо сырых байт картинки
|
|
// Если пришел JSON вместо сырых байт картинки
|
|
|
- sendPort.send(null);
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
} catch (_) {
|
|
} catch (_) {
|
|
|
// Если это не JSON (значит, скорее всего, чистые байты картинки) — всё отлично
|
|
// Если это не JSON (значит, скорее всего, чистые байты картинки) — всё отлично
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- sendPort.send(response.bodyBytes);
|
|
|
|
|
- return; // Успешно выходим из функции
|
|
|
|
|
|
|
+ return response.bodyBytes; // Успешно возвращаем результат
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Если код не 200 (например 500), увеличиваем таймаут и пробуем снова
|
|
// Если код не 200 (например 500), увеличиваем таймаут и пробуем снова
|
|
@@ -83,13 +119,12 @@ class HttpGetImage {
|
|
|
// В дебаге это частая история. Увеличиваем время и идем на следующую итерацию.
|
|
// В дебаге это частая история. Увеличиваем время и идем на следующую итерацию.
|
|
|
time++;
|
|
time++;
|
|
|
if (time > count) {
|
|
if (time > count) {
|
|
|
- sendPort.send(null);
|
|
|
|
|
- return;
|
|
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Если превысили лимит count и ничего не вернули
|
|
// Если превысили лимит count и ничего не вернули
|
|
|
- sendPort.send(null);
|
|
|
|
|
|
|
+ return null;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|