IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter学习-网络请求 -> 正文阅读

[移动开发]Flutter学习-网络请求

前言:项目中展示的大部分数据都是来自服务器,我们需要向服务器请求数据,并且对他们进行解析展示。
向服务器发出请求就需要用到网络请求相关的知识。

1. 网络请求的方式

在Flutter中常见的网络请求方式有三种:HttpClient、http库、dio库;

1.1 HttpClient的示例

HttpClient是dart自带的请求类,在io包中,实现了基本的网络请求相关的操作。

网络调用通常遵循如下步骤:

  1. 创建 client.
  2. 构造 Uri.
  3. 发起请求, 等待请求,同时您也可以配置请求headers、 body。
  4. 关闭请求, 等待响应.
  5. 解码响应的内容.

网络请求案例:

void requestNetwotk() async {
    //1. 创建HttpClient的请求实例
    final httpClient = HttpClient();

    //2.构建请求的URI
    // https://httpbin.org/get
    // http://123.207.32.32:8000/api/v1/recommend
    // https://httpbin.org/post
    final uri = Uri.parse("https://httpbin.org/get");

    //3.构建请求 返回值类型是 Future<HttpClientRequest> 是一个未来的对象,使用await之后可以使用HttpClientRequest类型来接收
    HttpClientRequest request = await httpClient.getUrl(uri);//get请求
    //final request = await httpClient.postUrl(uri);//post请求

    //4.发送请求 
    HttpClientResponse response = await request.close();

    //判断请求结果
    if (response.statusCode == HttpStatus.ok) {
      //打印成功结果
      print(await response.transform(utf8.decoder).join());
    } else {
      print(response.statusCode);
    }
  }
  //关闭HttpClient
    httpClient.close();
  • 代码分析:
    • 新建HttpClient对象,通过 getUrl方法获取 HttpClientRequest
    • 通过HttpClientRequest.close(),发起Http请求, 获取 HttpClientResponse
    • 判断请求结果根据code码,response.statusCode来判断
    • HttpClientResponse是一个Stream对象,通过Utf8Decoder解码,然后join操作符转换成String对象,可以打印出HttpClientResponse 的字符串。
    • 关闭HttpClient
      在这里插入图片描述

HttpClient虽然可以发送正常的网络请求,但是会暴露过多的细节:

  • 比如需要主动关闭request请求,拿到数据后也需要手动的进行字符串解码
  • 在开发中,我们一般很多直接面向HttpClient进行网络请求并不是直接使用HttpClient,而是使用一些库来完成

注意:HttpClient其中还有很多知识,如果大家需要深入了解HttpClient,建议大家多看文档,多找资料学习

1.2 Http库

httpDart 官方提供的另一个网络请求类,相比于 HttpClient,易用性提升了不少。

但是,没有默认集成到Dart的SDK中,所以我们需要先在pubspec中依赖它:

大家如果需要找第三方库:https://pub.dev,直接在这个网站搜索:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • dev_dependencies: 表示是开发阶段导入,打包app是不会把这下面的依赖打包进去的

  • 导入并使用

void requestNeteorkThridHttp() async {
    // 1.创建Client
    final client = http.Client();

    // 2.构建uri
    final url = Uri.parse("http://123.207.32.32:8000/api/v1/recommend");

    // 3.发送请求
    final response = await client.get(url);

    // 4.获取结果
    if (response.statusCode == HttpStatus.ok) {
      print(response.body);
    } else {
      print(response.statusCode);
    }
  }

1.3 dio三方库

官方提供的HttpClient和http都可以正常的发送网络请求,但是对于现代的应用程序开发来说,我们通常要求的东西会更多:比如拦截器、取消请求、文件上传/下载、超时设置等等;
这个时候,我们可以使用一个在Flutter中非常流行的三方库:dio;
官网有对dio进行解释:

dio是一个强大的Dart Http请求库,支持Restful API、FormData、拦截器、请求取消、Cookie管理、文件上传/下载、超时、自定义适配器等…

使用dio三方库必然也需要先在pubspec中依赖它:
在这里插入图片描述

dio代码简单演练:

import 'package:dio/dio.dart';

void dioNetwork() async {
  // 1.创建Dio请求对象
  final dio = Dio();

  // 2.发送网络请求
  final response = await dio.get("http://123.207.32.32:8000/api/v1/recommend");

  // 3.打印请求结果
  if (response.statusCode == HttpStatus.ok) {
    print(response.data);
  } else {
    print("请求失败:${response.statusCode}");
  }
}

1.4 dio库的简单封装

建议大家在使用三方库的时候,必须要自己封装一层,防止后期三方库弃用和更换别的三方库,导致程序改动困难

更对并且具体的使用方法参考github上的源码和文档:https://github.com/flutterchina/dio

import 'package:dio/dio.dart';


class HttpConfig {
  static const String baseUrl = "https://httpbin.org";
  static const int timeOut = 5000;
}

class HttpRequest {
  static final BaseOptions _baseOptions = BaseOptions(baseUrl: HttpConfig.baseUrl,connectTimeout: HttpConfig.timeOut);
  //防止每次请求都创建一个新的Dio对象
  static final Dio _dio = Dio(_baseOptions);

  /**
   * 参数后面的  ? 作用: 表示该参数可以为null, 如果不加? 则必须附一个默认值, 获取标记为必传参数
   */
  static Future<T> request<T>(String url, {
    String method = "get",
    Map<String, dynamic>? params,
    Interceptor? inter}) async {
    //1.创建单独配置
    final options = Options(method: method);

    //创建一个全局的拦截器
    Interceptor interceptor = InterceptorsWrapper(
        onRequest: (options, handle) {
          print("请求拦截");
		// 1.在进行任何网络请求的时候, 可以添加一个loading显示

        // 2.很多页面的访问必须要求携带Token,那么就可以在这里判断是有Token

        // 3.对参数进行一些处理,比如序列化处理等
			
          return;
        },
        onResponse: (response, handle) {
          print("响应拦截");

          return;
        },
        onError: (err, handle) {
          print("错误拦截");

          return;
        }
    );
    List<Interceptor> inters = [interceptor];

    // 请求单独拦截器
    if (inter != null) {
      inters.add(inter);
    }

    // 统一添加到拦截器中
    _dio.interceptors.addAll(inters);

    //2.发送网络请求
    try {
      Response response = await _dio.request(url,queryParameters: params,options: options);
      return response.data;
    } on DioError catch(e) {
        return Future.error(e);
    }
  }
}

使用:

 HttpRequest.request("/get",method: "get",params: {"name":"gwy"}).then((value) {
                  print("请求数据回来=========$value");
                });

2. JSON的读取和解析

在开发中,我们经常会使用本地JSON或者从服务器请求数据后回去到JSON,拿到JSON后通常会将JSON转成Model对象来进行后续的操作,因为这样操作更加的方便,也更加的安全。
所以学习JSON的相关操作以及读取JSON后如何转成Model对象对于Flutter开发也非常重要。

2.1 本地JSON资源配置

JSON也属于一种资源,所以在使用之前需要先进行相关的配置,配置本地JSON文件和之前我们配置本地图片一样

在这里插入图片描述

2.2 JSON数据的读取解析

JSON资源读取

如果我们希望读取JSON资源,可以使用package:flutter/services.dart包中的rootBundle

rootBundle中有一个loadString方法,可以去加载JSON资源

  • 但是注意,查看该方法的源码,你会发现这个操作是一个异步的
Future<String> loadString(String key, { bool cache = true }) async {
  ...省略具体代码,可以自行查看源码
}

代码如下:

import 'package:flutter/services.dart' show rootBundle;

// 打印读取的结果是一个字符串
rootBundle.loadString("assets/yz.json").then((value) => print(value));

JSON字符串转化

拿到JSON字符串后,我们需要将其转成成我们熟悉的List和Map类型。
我们可以通过dart:convert包中的json.decode方法将其进行转化

代码如下:

// 1.读取json文件
String jsonString = await rootBundle.loadString("assets/yz.json");

// 2.转成List或Map类型
final jsonResult = json.decode(jsonString);

对象Model定义
将JSON转成了List和Map类型后,就可以将List中的一个个Map转成Model对象,所以我们需要定义自己的Model

class Anchor {
  String nickname;
  String roomName;
  String imageUrl;

  Anchor({
    this.nickname,
    this.roomName,
    this.imageUrl
  });

  Anchor.withMap(Map<String, dynamic> parsedMap) {
    this.nickname = parsedMap["nickname"];
    this.roomName = parsedMap["roomName"];
    this.imageUrl = parsedMap["roomSrc"];
  }
}

2.3 JSON解析代码

完整解析逻辑代码:

import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
import 'dart:async';

class Anchor {
  String nickname;
  String roomName;
  String imageUrl;

  Anchor({
    this.nickname,
    this.roomName,
    this.imageUrl
  });

  Anchor.withMap(Map<String, dynamic> parsedMap) {
    this.nickname = parsedMap["nickname"];
    this.roomName = parsedMap["roomName"];
    this.imageUrl = parsedMap["roomSrc"];
  }
}

Future<List<Anchor>> getAnchors() async {
  // 1.读取json文件
  String jsonString = await rootBundle.loadString("assets/yz.json");

  // 2.转成List或Map类型
  final jsonResult = json.decode(jsonString);

  // 3.遍历List,并且转成Anchor对象放到另一个List中
  List<Anchor> anchors = new List();
  for (Map<String, dynamic> map in jsonResult) {
    anchors.add(Anchor.withMap(map));
  }
  return anchors;
} 

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-07-24 11:36:36  更:2021-07-24 11:38:14 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/1 22:19:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码