Flutter- 网络请求

前言

FlutterGoogle开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动、Web、桌面和嵌入式平台。Flutter 开源、免费,拥有宽松的开源协议,适合商业项目。目前,Flutter已推出稳定的2.0版本。也是目前最火的跨平台开发工具之一

header-illustration.png

Dart支持的API请求

之前在Dart语言的学习中,我们直接可以很方便的使用Dart支持的网络请求,在Flutter中也一样,直接这样就可以获取数据源并将其进行展示

  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库也是我们常用的网络请求框架

添加依赖

http: ^0.12.2

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

数据请求与展示

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库是一个更强大的网络请求框架,支持更多的网络请求设置,拦截器,超时,Cookie,文传等各种设置

https://github.com/flutterchina/dio

添加依赖

dio: ^4.0.1

发起一个简单的请求

  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

添加一个异常处理

当访问出现异常时,比如资源访问失败,访问超时等

这里由于使用了await 的同步调用,所以需要使用try catch进行异常捕获,当api调用失败时会返回DioError里面封装了错误状态码,错误信息,以及错误类型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,
}

这里我使用错误的链接访问

  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

访问超时处理

某些时候当服务不稳定时,会导致请求时间过长,可以设置api的请求超时时间,这里为了测试我们设置1毫秒的超时时间

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

添加拦截器

拦截器是API请求的很重要一部分,我们可以全局拦截发出去的请求数据比如为其添加特殊的Header,或者可以拦截返回的数据信息用来做一些公共处理或者打印日志

添加库提供的日志拦截器,方便我们进行请求调试

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

也可以自定义拦截器,将请求的额链接替换到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);
  }));

数据转换

通常情况下我们会将API返回的Jason数据转换为我们的实体类,这样会方便我们获取其中的字段用于设置和使用

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

也可以直接安装插件JsonToDart去创建对应的实体类,这样也避免手动写字符串的风险

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}');

欢迎关注Mike的简书

Android 知识整理

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,372评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,368评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,415评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,157评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,171评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,125评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,028评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,887评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,310评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,533评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,690评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,411评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,004评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,812评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,693评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,577评论 2 353

推荐阅读更多精彩内容