Flutter's multi-platform adapter mechanism is as simple as that

Keywords: Android iOS network Mobile

We all know that Flutter achieves multi-end consistency in the presentation layer and consistent UI effects through rendering on Android and iOS platforms.So if you're just developing a triple library for Android, iOS, and Web, what's a good idea?

Flutter Network Request

Can be used when developing Flutter http Core Library .You can also use other encapsulated class libraries from the community, such as dio.Both of the underlying implementations are http_parser

If a developer accidentally uses platform-related libraries directly in flutter, it can cause platform extensions to run incorrectly, such as using http under the io package to execute in a browser.

http Core Library Platform adaptions have been made for us. Here's how he adapted them:

import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
void hello(){
  print('a.dart => hello');
  http.get('http://127.0.0.1:8080').then((response){
    debugPrint('response => ${response.statusCode} ${response.body}');
  });
}

This code can run on mobile devices or browser devices to get consistent output.

http Core Library

Now let's take the get request as an example and look at its internal logic:

In the http interface class, the _withClient is ultimately executed to select the Client's implementation class, similar to the static proxy effect.

Specifically, when compiled for web use, the final import uses src/browser_client.dart, with the underlying implementation of HttpRequest under dart:html and the final front-end ajax technology: XMLHttpRequests.

/// Used from conditional imports, matches the definition in `client_stub.dart`.
BaseClient createClient() => BrowserClient();

/// A `dart:html`-based HTTP client that runs in the browser and is backed by
/// XMLHttpRequests.
///
/// This client inherits some of the limitations of XMLHttpRequest. It ignores
/// the [BaseRequest.contentLength], [BaseRequest.persistentConnection],
/// [BaseRequest.followRedirects], and [BaseRequest.maxRedirects] fields. It is
/// also unable to stream requests or responses; a request will only be sent and
/// a response will only be returned once all the data is available.
class BrowserClient extends BaseClient 

For Non-Browsers using the IO class library, src/io_client.dart, the underlying implementation is HttpClient under dart:io

/// Used from conditional imports, matches the definition in `client_stub.dart`.
BaseClient createClient() => IOClient();

/// A `dart:io`-based HTTP client.
///
/// This is the default client when running on the command line.
class IOClient extends BaseClient 

Conditional Guide

Here is an interesting grammar:

How do the http core libraries achieve platform differences?

By looking at the package for src/client.dart, you can see the following code:

// ignore: uri_does_not_exist
import 'client_stub.dart'
    // ignore: uri_does_not_exist
    if (dart.library.html) 'browser_client.dart'
    // ignore: uri_does_not_exist
    if (dart.library.io) 'io_client.dart';

The special syntax used here in dart is actually: Conditional Guide .You can consult the dart documentation for details.

Simply put, it uses conditional import/export to differentiate the guide packages during compilation so that platform adaptions can be achieved.

Use the Conditional Guide as follows:

  • First, define an interface for multiend implementations.
  • import/export is used in the interface class to export the corresponding implementation class library on demand
export 'src/hw_none.dart' // Stub implementation
    if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
    if (dart.library.html) 'src/hw_html.dart'; // dart:html implementation

Working with scenes

This mechanism can be used for convenient multi-platform adapting.Similar Dios have a lead difference logic src/dio.dart.

import 'entry_stub.dart'
// ignore: uri_does_not_exist
    if (dart.library.html) 'entry/dio_for_browser.dart'
// ignore: uri_does_not_exist
    if (dart.library.io) 'entry/dio_for_native.dart';

By the way, look at the dependencies of dio and http.dio is an encapsulation library uploaded by http, which provides more convenient api, but of course it also brings learning costs, depending on the actual needs of the project.

|-- dio 3.0.7
|   |-- http_parser 3.1.3
|   |   |-- charcode...
|   |   |-- collection...
|   |   |-- source_span...
|   |   |-- string_scanner...
|   |   '-- typed_data...
|   '-- path...

|-- http 0.12.0+2
|   |-- async...
|   |-- http_parser...
|   |-- path...
|   '-- pedantic...

Posted by narimanam on Sun, 22 Dec 2019 12:12:36 -0800