flutter数据请求之Dio

作者: your_genius | 来源:发表于2019-07-07 23:34 被阅读4次

    从Server请求数据,flutter有三种方式:

    • flutter原生HttpClient
    • flutter三方库Dio
    • 借用Android 原生获取数据

    和Android native类似,flutter原生HttpClient比较弱,而且请求到的数据需要转换,所以实践中大家多不推荐使用。

    借用Android原生获取数据,是指使用Android native来获取数据(例如常用的okhttp),flutter直接使用获取到数据,这是特殊场景和业务决定的。

    Dio是一个强大的第三方flutter库,今天就用Dio来撸一把,请求一个免费API来获取数据,用ListView展示出来
    效果图如下


    效果图

    step 1 :导入Dio库

    在pubspec.yaml文件中depencies:下添加

      # 网络请求库
      dio: ^2.1.0
    

    注意,yaml文件中不要随便添加空格,否则会报错。
    导入Dio过程中我的项目报错了:

    The current Dart SDK version is 2.1.2-dev.0.0.flutter-0a7dcf17eb.
    

    dart版本过低,直接点击AS右上角flutter upgrade升级完了再packages get一次,大约1-2分钟就好了。

    step 2 :请求数据。

    核心代码

     Dio dio = new Dio();
     Response response = await dio.get(Apis.NewsApi);
    

    就是这么简单。
    其中Apis.NewsApi是一个静态的url

    https://v.juhe.cn/toutiao/index?type=shishang&key=483294d5e9b2202317817d0696b47a58
    

    为了避免误导,把请求数据的整个方法都贴上来

     ///使用Dio库获取新闻数据
      static Future<List<NewsItem>> getDioNewsItems() async{
        Dio dio = new Dio();
        Response response = await dio.get(Apis.NewsApi);
        print("Myhttp : response.data = "+ response.data.toString());
        ...
      }
    

    数据请求是异步的过程,所以需要使用async + await。
    使用print输出我们请求的结果如下:

    {
        reason: 成功的返回,
        result: {
            stat: 1,
            data: [
                {
                    uniquekey: f88d72157c503080eb2775051f18e901,
                    title: 上了年纪女人穿衣搭配不能盲目跟风,聪明女人都在穿这样的连衣裙,
                    date: 2019-07-0723: 16,
                    category: 时尚,
                    author_name: 穿搭那些事,
                    url: http: //mini.eastday.com/mobile/190707231633202.html,
                    thumbnail_pic_s: http: //09imgmini.eastday.com/mobile/20190707/20190707231633_53c82b5c3ab6af3947719462bd555b72_4_mwpm_03200403.jpg,
                    thumbnail_pic_s02: http: //09imgmini.eastday.com/mobile/20190707/20190707231633_53c82b5c3ab6af3947719462bd555b72_1_mwpm_03200403.jpg,
                    thumbnail_pic_s03: http: //09imgmini.eastday.com/mobile/20190707/20190707231633_53c82b5c3ab6af3947719462bd555b72_7_mwpm_03200403.jpg
                },
      ...
    

    step 3 : 处理数据。

    • 首先从response中取出数据
     Map<dynamic,dynamic> dataMap = response.data;
    

    "dynamic"类似于java中的泛型,可以对应所有的数据类型,无论是基本数据类型还是自定义类。这一步其实可以简写成

     Map dataMap = response.data;
    

    其实如果仔细看上面我们打印出来的日志就会发现有点不对劲,日志并不是json格式。因为Dio已经把json解析成了Map<dynamic,dynamic> 格式,但是Dio也只能帮我们到这里了,毕竟她不是Gson能一步到位给我们解析成对应的对象,下面的处理还要靠我们自己。

    • 其次处理数据格式。这一步我们要一层层处理dataMap中的数据了。
      (1) 处理属性“reason”和“result”
    class NewsAllBean{
    
      NewsAllBean(String reason, Map<String,dynamic> result){
        this.reason = reason;
        this.result = result;
        transformNewsData(result);
      }
      String reason;
      Map result;
      NewsData newsData; 
      
      //Map 映射成NewsData
      void transformNewsData(Map<String , dynamic> map){
        this.newsData = NewsData(map['stat'], map['data']);
      }
    }
    

    属性"reason"类型是String, 属性“ result” 类型是Map<dynamic, dynamic>这都是好理解的,NewsData是啥?是result对应的类。NewsData的属性就是result的Key

    (2)处理result的各个属性,并且将result映射成一个对象。

    class NewsData{
    
      NewsData(String stat,List<dynamic>data){
        this.stat = stat;
        this.data = data;
        transformItems(data);
      }
    
      String stat;
      List data;
      List<NewsItem> dataNews;
    
      //List data映射成List<NewsItem>
      void transformItems(List<dynamic> list){
    
        this.dataNews = list.map((i)=>NewsItem.fromMapJson(i)).toList();
      }
    
    
    }
    

    NewsData属性中有个List,Dio将其解析成List<dynamic> 类型,那么为了将其映射成我们想要的 List<NewsItem>类型,需要遍历这个List<dynamic>了

    (3)NewsItem。最基本的类了

    ///具体的每一条新闻的内容
    class NewsItem {
      NewsItem(
          {this.uniquekey,
          this.title,
          this.date,
          this.category,
          this.author_name,
          this.url,
          this.thumbnail_pic_s});
    
      String uniquekey; //":"779e0448503ff134fef798f81170b008",
      String title; //":"亚足联:2023年亚洲杯将由中国承办",
      String date; //":"2019-06-04 17:06",
      String category; //":"头条",
      String author_name; //":"央视网",
      String url; //":"http:\/\/mini.eastday.com\/mobile\/190604170654219.html",
      String
          thumbnail_pic_s; //":"http:\/\/05imgmini.eastday.com\/mobile\/20190604\/20190604170654_6fb492fbe34b25ca811121c7a7ea3c56_1_mwpm_03200403.jpg"
    
      static NewsItem fromMapJson(Map<String, dynamic> mapjson) {
        return NewsItem(
            uniquekey: mapjson['uniquekey'],
            title: mapjson['title'],
            date: mapjson['date'],
            category: mapjson['category'],
            author_name: mapjson['author_name'],
            url: mapjson['url'],
            thumbnail_pic_s: mapjson['thumbnail_pic_s']);
      }
    }
    

    至此,我们完成了数据请求与数据解析。

    使用数据

    使用数据的过程比较easy,有兴趣可以直接看代码newsGet.dart
    Demo地址
    欢迎留言交流~

    相关文章

      网友评论

        本文标题:flutter数据请求之Dio

        本文链接:https://www.haomeiwen.com/subject/vphwhctx.html