runWithClient<R> function
Runs body
in its own Zone with the Client returned by clientFactory
set as the default Client.
For example:
class MyAndroidHttpClient extends BaseClient {
@override
Future<http.StreamedResponse> send(http.BaseRequest request) {
// your implementation here
}
}
void main() {
var clientFactory = Client.new; // Constructs the default client.
if (Platform.isAndroid) {
clientFactory = MyAndroidHttpClient.new;
}
runWithClient(myFunction, clientFactory);
}
void myFunction() {
// Uses the `Client` configured in `main`.
final response = await get(Uri.https('www.example.com', ''));
final client = Client();
}
The Client returned by clientFactory
is used by the Client.new factory
and the convenience HTTP functions (e.g. http.get). If clientFactory
returns Client()
then the default Client is used.
When used in the context of Flutter, runWithClient should be called before
WidgetsFlutterBinding.ensureInitialized
because Flutter runs in whatever Zone was current at the time that the
bindings were initialized.
runApp
calls
WidgetsFlutterBinding.ensureInitialized
so the easiest approach is to call that in body
:
void main() {
var clientFactory = Client.new; // Constructs the default client.
if (Platform.isAndroid) {
clientFactory = MyAndroidHttpClient.new;
}
runWithClient(() => runApp(const MyApp()), clientFactory);
}
If runWithClient is used and the environment defines
no_default_http_client=true
then generated binaries may be smaller e.g.
$ flutter build appbundle --dart-define=no_default_http_client=true ...
$ dart compile exe --define=no_default_http_client=true ...
If no_default_http_client=true
is set then any call to the Client
factory (i.e. Client()
) outside of the Zone created by runWithClient
will throw StateError.
Implementation
R runWithClient<R>(R Function() body, Client Function() clientFactory,
{ZoneSpecification? zoneSpecification}) =>
runZoned(body,
zoneValues: {#_clientToken: Zone.current.bindCallback(clientFactory)},
zoneSpecification: zoneSpecification);