-
Notifications
You must be signed in to change notification settings - Fork 358
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
runWithClient cannot be used to configure the client in the root Zone #828
Comments
It makes me sad if we can't use Zones for the use case they fit best. |
Fixed in d434d42 |
@kevmoo while doing some intense testing with a network monitor I just had to find out that Flutter ignores the HttpClient that I provide with |
@escamoteur You can look at flutter_http_example to see how you can plumb a |
I tried it and it does not work. I could see in Fiddler, that network images were still retrieved with a http 1.1 client.
Only after adding my own Network ClientProvider did it work. NetworkImage ignores the client you pass via runWithClient.
Am 25. Juni 2024, 20:56 +0100 schrieb Brian Quinlan ***@***.***>:
… @escamoteur You can look at flutter_http_example to see how you can plumb a package:http Client through a Flutter application - including using it to load images.
—
Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you were mentioned.Message ID: ***@***.***>
|
I just checked your example, there you too use a different ImageProvider than the built in from Flutter.
Am 25. Juni 2024, 21:09 +0100 schrieb ***@***.***:
… I tried it and it does not work. I could see in Fiddler, that network images were still retrieved with a http 1.1 client.
Only after adding my own Network ClientProvider did it work. NetworkImage ignores the client you pass via runWithClient.
Am 25. Juni 2024, 20:56 +0100 schrieb Brian Quinlan ***@***.***>:
> @escamoteur You can look at flutter_http_example to see how you can plumb a package:http Client through a Flutter application - including using it to load images.
> —
> Reply to this email directly, view it on GitHub, or unsubscribe.
> You are receiving this because you were mentioned.Message ID: ***@***.***>
|
That's correct. |
And that was my point, according to the documentation Unfortunately, the package you used doesn't have a linked github repository which isn't really good for an official example. I would propose you just add an ImageProvider like the following (this here uses get_it instead of provider so you don't even have to pass the client to every Image widget) directly inside your demo project. class HttpNetworkImage extends ImageProvider<HttpNetworkImage> {
/// Creates an object that fetches the image at the given URL.
const HttpNetworkImage(this.url, {this.scale = 1.0, this.headers});
final String url;
final double scale;
final Map<String, String>? headers;
@override
Future<HttpNetworkImage> obtainKey(ImageConfiguration configuration) {
return SynchronousFuture<HttpNetworkImage>(this);
}
@override
ImageStreamCompleter loadImage(
HttpNetworkImage key, ImageDecoderCallback decode) {
// Ownership of this controller is handed off to [_loadAsync]; it is that
// method's responsibility to close the controller's stream when the image
// has been loaded or an error is thrown.
return MultiFrameImageStreamCompleter(
codec: _loadAsync(key, decode: decode),
scale: key.scale,
debugLabel: key.url,
informationCollector: () => <DiagnosticsNode>[
DiagnosticsProperty<ImageProvider>('Image provider', this),
DiagnosticsProperty<HttpNetworkImage>('Image key', key),
],
);
}
Future<ui.Codec> _loadAsync(
HttpNetworkImage key, {
required ImageDecoderCallback decode,
}) async {
try {
assert(key == this);
final Uri resolved = Uri.base.resolve(key.url);
final response = await GetIt.I<Client>().get(resolved, headers: headers);
if (response.statusCode != HttpStatus.ok) {
// The network may be only temporarily unavailable, or the file will be
// added on the server later. Avoid having future calls to resolve
// fail to check the network again.
// await response.drain<List<int>>(<int>[]);
throw NetworkImageLoadException(
statusCode: response.statusCode, uri: resolved);
}
if (response.bodyBytes.isEmpty) {
throw Exception('NetworkImage is an empty file: $resolved');
}
return decode(await ui.ImmutableBuffer.fromUint8List(response.bodyBytes));
} catch (e) {
// Depending on where the exception was thrown, the image cache may not
// have had a chance to track the key in the cache at all.
// Schedule a microtask to give the cache a chance to add the key.
scheduleMicrotask(() {
PaintingBinding.instance.imageCache.evict(key);
});
rethrow;
}
}
@override
bool operator ==(Object other) {
if (other.runtimeType != runtimeType) {
return false;
}
return other is HttpNetworkImage && other.url == url && other.scale == scale;
}
@override
int get hashCode => Object.hash(url, scale);
@override
String toString() =>
'${objectRuntimeType(this, 'NetworkImage')}("$url", scale: ${scale.toStringAsFixed(1)})';
} |
Towards #828 Add a section in the `runWithClient` doc that mentions HTTP requests which _aren't_ affected by usage of this API - specifically requests made through the SDK core libraries, or through instantiating specific client implementations.
Towards #828 Add a section in the `runWithClient` doc that mentions HTTP requests which _aren't_ affected by usage of this API - specifically requests made through the SDK core libraries, or through instantiating specific client implementations.
runWithClient
is not sufficient for the Flutter use case.Flutter sometimes invokes callbacks on the Root Zone and
runWithClient
cannot be used to setClient
in thatZone
.The text was updated successfully, but these errors were encountered: