跳转至

网络

网络请求库

  1. dio
  2. http

无论哪种三方的网络请求,自己都要封装,否则更改第三方的时候要全部修改,地方太多。

切换第三方只需要把封装好的给改一下就可以了。

别名

在 Dart中,可以使用 as 关键字为类、函数或者库起别名。这在导入多个库时,如果这些库中有相同名称的类或者函数,起别名可以帮助避免冲突。

以下是一个例子,假设有两个库,package1package2,都有一个名为 MyClass 的类,你可以为其中一个起一个别名:

import 'package:package1/package1.dart';
import 'package:package2/package2.dart' as pkg2;

void main() {
  var a = MyClass();  // 这是来自 package1 的 MyClass
  var b = pkg2.MyClass();  // 这是来自 package2 的 MyClass
}

在这个例子中, pkg2package2 的别名,你可以使用 pkg2.MyClass() 来创建一个 package2 中的 MyClass 实例,以此避免与 package1 中的 MyClass 冲突。

使用

  1. 拷贝http: ^0.13.4

然后进入到pubspec.yaml 导入

  1. 导入头文件

http使用

import 'dart:convert';

import 'package:http/http.dart' as http;

class Chat {
  final String? name;
  final String? message;
  final String? imageUrl;
  Chat({this.name, this.message, this.imageUrl});
  //工厂构造 可以有返回值
  factory Chat.formMap(Map map) {
    return Chat(
      name: map['name'],
      message: map['message'],
      imageUrl: map['imageUrl'],
    );
  }
}

//异步获取数据
Future<List<Chat>> getDatas() async {
  final url =
      Uri.parse('http://rap2api.taobao.org/app/mock/295570/api/chat/list');
  //发送请求
  final response = await http.get(url); //异步获取数据 会等,但是不会卡住UI。
  // print(response.statusCode);
  // print(response.body);
  if (response.statusCode == 200) {
    //获取响应数据,json数据转成Map类型 类似字典
    final responsBody = json.decode(response.body);
    List<Chat> chatList = responsBody['chat_list']
        .map<Chat>((item) => Chat.formMap(item))
        .toList(); //map():List的遍历方法
    // print(chatList);
    return chatList;
  } else {
    throw Exception('statusCode:${response.statusCode}');
  }
}

dio使用

import 'dart:io'; //保存文件路径

import 'package:dio/dio.dart';

///简单的网络请求
void dioDemo() {
  //发送网络请求
  final dio = Dio();
  dio.get('https://www.baidu.com').then((value) => print(value));
}

void downloadDemo() {
  //发送网络请求
  //1.创建dio对象
  final dio = Dio();
  //2.下载数据
  var downloadUrl =
      'https://edu-files-1251502357.cos.ap-shanghai.myqcloud.com/CourseTeacher_2.8.2.24_DailyBuild.dmg';
  String savePath = '/Users/michael/Desktop/123/腾讯课堂.dmg';
  // download1(dio, downloadUrl, savePath);
  download2(dio, downloadUrl, savePath);
}

///存到手机本地
void download2(Dio dio, String url, String savePath) {
  //手机端
  String iOSPath = Directory.systemTemp.path + '腾讯课堂.dmg';
  print(iOSPath);
  dio
      .download(url, (Headers headers) {
        // // Extra info: redirect counts
        // print(headers.value('redirects'));
        // // Extra info: real uri
        // print(headers.value('uri'));
        return iOSPath;
      }, onReceiveProgress: showDownloadProgress)
      .whenComplete(() => print('下载完成'))
      .catchError((e) => print(e));
}

///保存到电脑
void download1(Dio dio, String url, String savePath) {
  dio
      .download(url, savePath, onReceiveProgress: showDownloadProgress)
      .then((value) => print(value))
      .whenComplete(() => print('结束了'))
      .catchError((e) => print(e));
}

///下载进度
void showDownloadProgress(int count, int total) {
  // print('count:$count  total:$total');
  if (total != -1) {
    print((count / total * 100).toStringAsFixed(0) + '%');
  }
}

网络请求是异步的,调用的时候不需要等,去做别的。

线程是由CPU调度。

多线程一定是异步的,但是异步不一定是多线程。

任务A 任务B 任务C 可以是一个线程A,是异步的,但是同一个线程。