Flutter(十)网络请求和文件

这篇具有很好参考价值的文章主要介绍了Flutter(十)网络请求和文件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

文件操作

APP目录
Android 和 iOS 的应用存储目录不同,PathProvider (opens new window)插件提供了一种平台透明的方式来访问设备文件系统上的常用位置。该类当前支持访问两个文件系统位置:

  • 临时目录: getTemporaryDirectory() ,可以使用 来获取临时目录; 系统可随时清除临时目录的文件。在 Android上,这是getCacheDir() (opens new window)返回的值,在 iOS 上,这对应于NSTemporaryDirectory() (opens new window)返回的值。

  • 文档目录: getApplicationDocumentsDirectory()来获取应用程序的文档目录,该目录用于存储只有自己可以访问的文件。只有当应用程序被卸载时,系统才会清除该目录。
    在 Android 上,这是AppData目录,在 iOS 上,这对应于NSDocumentDirectory。。

  • 外部存储目录:getExternalStorageDirectory()来获取外部存储目录,如 SD 卡;
    Android 下结果是Android SDK 中getExternalStorageDirectory的返回值。
    iOS不支持外部目录,所以在 iOS 下调用该方法会抛出UnsupportedError异常,

使用:
pubspec.yaml中添加引用:path_provider: ^2.0.2
文件读写演示:

import 'dart:io';
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

class FileOperationRoute extends StatefulWidget {
  FileOperationRoute({Key? key}) : super(key: key);

  @override
  _FileOperationRouteState createState() => _FileOperationRouteState();
}

class _FileOperationRouteState extends State<FileOperationRoute> {
  int _counter = 0;

  @override
  void initState() {
    super.initState();
    //从文件读取点击次数
    _readCounter().then((int value) {
      setState(() {
        _counter = value;
      });
    });
  }

  Future<File> _getLocalFile() async {
    // 获取应用目录
    String dir = (await getApplicationDocumentsDirectory()).path;
    return File('$dir/counter.txt');
  }

  Future<int> _readCounter() async {
    try {
      File file = await _getLocalFile();
      // 读取点击次数(以字符串)
      String contents = await file.readAsString();
      return int.parse(contents);
    } on FileSystemException {
      return 0;
    }
  }

  _incrementCounter() async {
    setState(() {
      _counter++;
    });
    // 将点击次数以字符串类型写到文件中
    await (await _getLocalFile()).writeAsString('$_counter');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('文件操作')),
      body: Center(
        child: Text('点击了 $_counter 次'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

在实际开发中,如果要存储一些简单的数据,使用shared_preferences插件会比较简单

网络请求

1.Dio库

发起 GET 请求 :

Response response;
response=await dio.get("/test?id=12&name=wendu")
print(response.data.toString());

对于GET请求我们可以将query参数通过对象来传递,上面的代码等同于:

response=await dio.get("/test",queryParameters:{"id":12,"name":"wendu"})
print(response);

发起一个 POST 请求:

response=await dio.post("/test",data:{"id":12,"name":"wendu"})

发起多个并发请求:

response= await Future.wait([dio.post("/info"),dio.get("/token")]);

下载文件:

response=await dio.download("https://www.google.com/",_savePath);

发送 FormData:

FormData formData = FormData.from({
   "name": "wendux",
   "age": 25,
});
response = await dio.post("/info", data: formData)

如果发送的数据是FormData,则dio会将请求header的contentType设为“multipart/form-data”。

通过FormData上传多个文件:

FormData formData = FormData.from({
   "name": "wendux",
   "age": 25,
   "file1": UploadFileInfo(File("./upload.txt"), "upload1.txt"),
   "file2": UploadFileInfo(File("./upload.txt"), "upload2.txt"),
     // 支持文件数组上传
   "files": [
      UploadFileInfo(File("./example/upload.txt"), "upload.txt"),
      UploadFileInfo(File("./example/upload.txt"), "upload.txt")
    ]
});
response = await dio.post("/info", data: formData)

dio内部仍然使用HttpClient发起的请求,所以代理、请求认证、证书校验等和HttpClient是相同的,我们可以在onHttpClientCreate回调中设置,例如:

(dio.httpClientAdapter as DefaultHttpClientAdapter).onHttpClientCreate = (client) {
    //设置代理 
    client.findProxy = (uri) {
      return "PROXY 192.168.1.2:8888";
    };
    //校验证书
    httpClient.badCertificateCallback=(X509Certificate cert, String host, int port){
      if(cert.pem==PEM){
      return true; //证书一致,则允许发送数据
     }
     return false;
    };   
  };

注意,onHttpClientCreate会在当前dio实例内部需要创建HttpClient时调用,所以通过此回调配置HttpClient会对整个dio实例生效,如果应用需要多种代理或证书校验策略,可以创建不同的dio实例来分别实现。

dio主页:https://github.com/flutterchina/dio

2.websocket

演示WebSocket通信过程

import 'package:flutter/material.dart';
import 'package:web_socket_channel/io.dart';

class WebSocketRoute extends StatefulWidget {
  @override
  _WebSocketRouteState createState() => _WebSocketRouteState();
}

class _WebSocketRouteState extends State<WebSocketRoute> {
  TextEditingController _controller = TextEditingController();
  IOWebSocketChannel channel;
  String _text = "";


  @override
  void initState() {
    //创建websocket连接
    channel = IOWebSocketChannel.connect('wss://echo.websocket.events');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("WebSocket(内容回显)"),
      ),
      body: Padding(
        padding: const EdgeInsets.all(20.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: <Widget>[
            Form(
              child: TextFormField(
                controller: _controller,
                decoration: InputDecoration(labelText: 'Send a message'),
              ),
            ),
            //当服务器传输的数据是指定为二进制时,StreamBuilder的snapshot.data的类型就是List<int>,是文本时,则为String
            StreamBuilder(
              stream: channel.stream,
              builder: (context, snapshot) {
                //网络不通会走到这
                if (snapshot.hasError) {
                  _text = "网络不通...";
                } else if (snapshot.hasData) {
                  _text = "echo: "+snapshot.data;
                }
                return Padding(
                  padding: const EdgeInsets.symmetric(vertical: 24.0),
                  child: Text(_text),
                );
              },
            )
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _sendMessage,
        tooltip: 'Send message',
        child: Icon(Icons.send),
      ),
    );
  }

  void _sendMessage() {
    if (_controller.text.isNotEmpty) {
      channel.sink.add(_controller.text);
    }
  }

  @override
  void dispose() {
    channel.sink.close();
    super.dispose();
  }
}


3.JSON转Dart Model

  1. Android Studio - Settings - Plugins - 搜索JsonToDart 插件
  2. 文件夹右键New - Json To Dart - 输入json文件自动生成

生成示例如下:文章来源地址https://www.toymoban.com/news/detail-688353.html

import 'as_t.dart';

class HotKeyModel {
  int? id;
  String? link;
  String? name;
  int? order;
  int? visible;

  HotKeyModel({this.id, this.link, this.name, this.order, this.visible});

  HotKeyModel.fromJson(Map<String, dynamic> json) {
    id = asT<int?>(json['id']);
    link = asT<String?>(json['link']);
    name = asT<String?>(json['name']);
    order = asT<int?>(json['order']);
    visible = asT<int?>(json['visible']);
  }

  Map<String, dynamic> toJson() {
    final Map<String, dynamic> data = {};
    data['id'] = this.id;
    data['link'] = this.link;
    data['name'] = this.name;
    data['order'] = this.order;
    data['visible'] = this.visible;
    return data;
  }
}

到了这里,关于Flutter(十)网络请求和文件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter Web 项目网络请求报 XMLHttpRequest error 解决方案

    使用http库进行简单的网络请求时,运行在Chrome浏览器上,网络请求一直报错 XMLHttpRequest error,而在iOS 模拟器上运行则正常,后面在postman上发送请求,也是正常的。这就是很尴尬了!!! 经多番查阅,是跨域问题,解决方案如下: 1.找到flutter sdk目录 2.然后找到flutterpackage

    2024年02月11日
    浏览(36)
  • Flutter网络请求框架Dio源码分析以及封装(二)--Cookie管理分析

    上一篇文章我们简单分析了一下Dio发出请求时的大致工作流程,这个只是Dio最基本的功能,而且我们还没有分析走到httpClientAdapter之后的内容。不过不用着急,这次我们先接着上一次的内容,看一下Dio当中Cookie管理的问题,因为之前在项目中碰到了这个问题,回过头来再从源

    2024年02月08日
    浏览(42)
  • Flutter 网络请求报错 Failed host lookup: ‘ 地址‘ (OS Error: No address associated with hostname, errno =

    设备无网络 检查设备有网络 没有配置网络权限 在android/src/main/AndroidManifest.xml中 manifest 标签中配置一下权限: 注意:不要填写到 application 标签中

    2024年02月02日
    浏览(35)
  • Flutter之dio请求封装

    dio是一个http请求库,功能十分强大,支持Restful API、请求取消、FormData、拦截器等,下面我们对dio进行简单的封装,这样我们在项目中使用时会更顺手,这里还需要配合AndroidStudio的 jsonToDartBeanAction插件配合使用 打开我们的flutter的项目的pubspec.yaml 文件,然后在dependencies 中添加依

    2024年02月14日
    浏览(46)
  • flutter dio 请求封装(空安全)

    2024年02月06日
    浏览(59)
  • Flutter携带JSON参数post请求

    在Flutter中发送带有JSON参数的网络请求,你可以使用HTTP库(如 http 或 dio )来实现。以下是使用 http 库发送网络请求并携带JSON参数的示例: 在上述示例中,首先创建一个参数Map,并将其转换为JSON字符串。然后设置请求头,使其指明请求类型为JSON。最后使用 http.post() 方法发送

    2024年02月14日
    浏览(54)
  • flutter开发实战-请求dio设置Cookie

    flutter开发实战-请求dio设置Cookie 在最近开发中碰到了需要websocket长链接收到响应的auth,在之后的请求中需要将其设置为cookie中。 如Cookie:auth=DHSfQQSAXf89xZqJTLdEDVI2hwzc7p2lUmSNNdUSlgW2MyfQIN+pYr7jUbkX/; 设置cookie用到了dio_cookie_manager组件 在pubspec.yaml引入dio_cookie_manager 2.1 使用CookieJar Cookie

    2024年02月15日
    浏览(60)
  • Flutter dio Http请求之Cookie管理

    在应用开发过程中,我们进行Http通讯时会使用 Cookie 进行验证,今天我们就着重讲解Flutter 网络请求插件 dio 的 cookie 使用。 首先,我们要进行插件引用 这里为什么要使用 path_provider 这个插件呢,下面在 cookie 的储存时会做介绍。 引用完,我们执行以下命令 dio 的使用网上有很

    2024年02月20日
    浏览(38)
  • flutter动态渲染从服务器请求的列表数据

    比如我们从服务器请求到的列表数据,需要渲染到页面上,但是在flutter里面还是需要使用他们的ListView或者GridView或者别的组件才可以,或者有children这种属性的组件上使用。 比如我们在一个有状态的组件Lists里面,在initState的时候,发送请求获取数据,并将获取到的数据通过

    2024年01月16日
    浏览(44)
  • Flutter笔记:关于Flutter中的大文件上传(上)

    Flutter笔记 关于Flutter中的大文件上传(上) 大文件上传背景与 Flutter 端实现文件分片传输 作者 : 李俊才 (jcLee95):https://blog.csdn.net/qq_28550263 邮箱 : 291148484@163.com 本文地址 :https://blog.csdn.net/qq_28550263/article/details/134302751 本系列上下两篇文章,包括 Flutter 端和 Django 端(后

    2024年02月03日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包