Flutter- 網(wǎng)絡(luò)請(qǐng)求

前言

FlutterGoogle開源的構(gòu)建用戶界面(UI)工具包,幫助開發(fā)者通過一套代碼庫高效構(gòu)建多平臺(tái)精美應(yīng)用,支持移動(dòng)、Web、桌面和嵌入式平臺(tái)。Flutter 開源、免費(fèi),擁有寬松的開源協(xié)議,適合商業(yè)項(xiàng)目。目前,Flutter已推出穩(wěn)定的2.0版本。也是目前最火的跨平臺(tái)開發(fā)工具之一

header-illustration.png

Dart支持的API請(qǐng)求

之前在Dart語言的學(xué)習(xí)中,我們直接可以很方便的使用Dart支持的網(wǎng)絡(luò)請(qǐng)求,在Flutter中也一樣,直接這樣就可以獲取數(shù)據(jù)源并將其進(jìn)行展示

  readData() async {
    HttpClientResponse response = await getBaiduData();
    String res = await response.transform(utf8.decoder).join();
    setState(() {
      data = res;
    });
  }

  getBaiduData() async {
    HttpClient client = HttpClient();
    var request = await client.getUrl(Uri.http("www.baidu.com", ""));
    var response = await request.close();
    return response;
  }

Http庫

Http庫也是我們常用的網(wǎng)絡(luò)請(qǐng)求框架

添加依賴

http: ^0.12.2

https://github.com/dart-lang/http

數(shù)據(jù)請(qǐng)求與展示

class HomePageStates extends State<HomePage>
    with SingleTickerProviderStateMixin {
  String data = "";
  bool isShowLoading = false;

  @override
  void initState() {
    super.initState();
  }

  getData() async {
    setState(() {
      isShowLoading = true;
    });
     var http = Client();
     Response response = await http.get("https://jsonplaceholder.typicode.com/todos/1");
     setState(() {
       data = response.body;
       isShowLoading = false;
     });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('Home'),
          centerTitle: true,
        ),
        body: Stack(
          children: [
            Container(
              alignment: Alignment.center,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  Text('$data'),
                  Ink(
                    decoration: BoxDecoration(
                        color: Colors.green,
                        borderRadius: BorderRadius.circular(20)),
                    child: InkWell(
                      borderRadius: BorderRadius.circular(20),
                      onTap: () {
                        getData();
                      },
                      splashColor: Colors.white,
                      child: Container(
                        width: 100,
                        height: 40,
                        alignment: Alignment.center,
                        child: Text(
                          'Get',
                          style: TextStyle(color: Colors.white),
                        ),
                      ),
                    ),
                  ),
                ],
              ),
            ),
            Visibility(
              visible: isShowLoading,
                child: Container(
              alignment: Alignment.center,
              child: Container(
                width: double.maxFinite,
                height: double.maxFinite,
                child: Center(
                  child: SizedBox(
                    height: 40,
                    width: 40,
                    child: CircularProgressIndicator(
                      strokeWidth: 2,
                      valueColor: AlwaysStoppedAnimation<Color>(Colors.blue),
                    ),
                  ),
                ),
              ),
            ))
          ],
        ));
  }
}
http.png

dio

dio庫是一個(gè)更強(qiáng)大的網(wǎng)絡(luò)請(qǐng)求框架,支持更多的網(wǎng)絡(luò)請(qǐng)求設(shè)置,攔截器,超時(shí),Cookie,文傳等各種設(shè)置

https://github.com/flutterchina/dio

添加依賴

dio: ^4.0.1

發(fā)起一個(gè)簡(jiǎn)單的請(qǐng)求

  getData() async {
    setState(() {
      isShowLoading = true;
    });

    var dio = Dio();
    var response =
    await dio.get("https://jsonplaceholder.typicode.com/todos/1");
    data = response.data.toString();
    setState(() {
      data = response.data.toString();
      isShowLoading = false;
    });
  }
dio.png

添加一個(gè)異常處理

當(dāng)訪問出現(xiàn)異常時(shí),比如資源訪問失敗,訪問超時(shí)等

這里由于使用了await 的同步調(diào)用,所以需要使用try catch進(jìn)行異常捕獲,當(dāng)api調(diào)用失敗時(shí)會(huì)返回DioError里面封裝了錯(cuò)誤狀態(tài)碼,錯(cuò)誤信息,以及錯(cuò)誤類型DioErrorType 用于做判斷

enum DioErrorType {
  /// It occurs when url is opened timeout.
  connectTimeout,

  /// It occurs when url is sent timeout.
  sendTimeout,

  ///It occurs when receiving timeout.
  receiveTimeout,

  /// When the server response, but with a incorrect status, such as 404, 503...
  response,

  /// When the request is cancelled, dio will throw a error with this type.
  cancel,

  /// Default error type, Some other Error. In this case, you can
  /// use the DioError.error if it is not null.
  other,
}

這里我使用錯(cuò)誤的鏈接訪問

  getData() async {
    setState(() {
      isShowLoading = true;
    });

    try {
      var dio = Dio();
      var response =
          await dio.get("https://jsonplaceholder.typicode.com/todos/1test");
      data = response.data.toString();
    } on DioError catch (e) {
      data =
          "error ${e.type}---${e.response?.statusCode}---${e.response?.statusMessage}";
    } catch (e) {
      //other exception
      data = "other error ${e.toString()}";
    } finally {
      setState(() {
        isShowLoading = false;
      });
    }
  }
error.png

訪問超時(shí)處理

某些時(shí)候當(dāng)服務(wù)不穩(wěn)定時(shí),會(huì)導(dǎo)致請(qǐng)求時(shí)間過長(zhǎng),可以設(shè)置api的請(qǐng)求超時(shí)時(shí)間,這里為了測(cè)試我們?cè)O(shè)置1毫秒的超時(shí)時(shí)間

var dio = Dio(BaseOptions(receiveTimeout: 1,connectTimeout: 1,sendTimeout: 1));
timeout.png

添加攔截器

攔截器是API請(qǐng)求的很重要一部分,我們可以全局?jǐn)r截發(fā)出去的請(qǐng)求數(shù)據(jù)比如為其添加特殊的Header,或者可以攔截返回的數(shù)據(jù)信息用來做一些公共處理或者打印日志

添加庫提供的日志攔截器,方便我們進(jìn)行請(qǐng)求調(diào)試

var dio = Dio(BaseOptions(receiveTimeout: 10000,connectTimeout: 10000,sendTimeout: 10000)).interceptors.add(LogInterceptor());

也可以自定義攔截器,將請(qǐng)求的額鏈接替換到https://jsonplaceholder.typicode.com/todos/2

dio.interceptors.add(InterceptorsWrapper(onRequest: (options,handler){
    options.headers['from'] = 'Mike_Test';
    options.path = "https://jsonplaceholder.typicode.com/todos/2";
    handler.next(options);
  }));

數(shù)據(jù)轉(zhuǎn)換

通常情況下我們會(huì)將API返回的Jason數(shù)據(jù)轉(zhuǎn)換為我們的實(shí)體類,這樣會(huì)方便我們獲取其中的字段用于設(shè)置和使用

var maps = json.decode("{\"id\":\"2\"}");
var model = ResponseModel(maps["id"]);
print(model.id);

也可以直接安裝插件JsonToDart去創(chuàng)建對(duì)應(yīng)的實(shí)體類,這樣也避免手動(dòng)寫字符串的風(fēng)險(xiǎn)

https://plugins.jetbrains.com/plugin/12562-jsontodart-json-to-dart-

/// id : "2"

class ResponseModel {
  ResponseModel({
    required String id,}){
    _id = id;
  }

  ResponseModel.fromJson(dynamic json) {
    _id = json['id'];
  }
  String _id ="";

  String get id => _id;

  Map<String, dynamic> toJson() {
    final map = <String, dynamic>{};
    map['id'] = _id;
    return map;
  }

}
var model = ResponseModel.fromJson(json.decode("{\"id\":\"2\"}"));
print('${model.id}');

歡迎關(guān)注Mike的簡(jiǎn)書

Android 知識(shí)整理

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容