当前位置: 首页 > news >正文

Flutter(十)网络请求和文件

目录

  • 文件操作
  • 网络请求
    • 1.Dio库
    • 2.websocket
    • 3.JSON转Dart Model

文件操作

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;@overridevoid 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');}@overrideWidget 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 = "";@overridevoid initState() {//创建websocket连接channel = IOWebSocketChannel.connect('wss://echo.websocket.events');}@overrideWidget 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>,是文本时,则为StringStreamBuilder(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);}}@overridevoid dispose() {channel.sink.close();super.dispose();}
}

3.JSON转Dart Model

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

生成示例如下:

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(十)网络请求和文件

目录 文件操作网络请求1.Dio库2.websocket3.JSON转Dart Model 文件操作 APP目录 Android 和 iOS 的应用存储目录不同&#xff0c;PathProvider (opens new window)插件提供了一种平台透明的方式来访问设备文件系统上的常用位置。该类当前支持访问两个文件系统位置&#xff1a;…...

Unity RenderStreaming 云渲染-黑屏

&#x1f96a;云渲染-黑屏 网页加载出来了&#xff0c;点击播放黑屏 &#xff0c;关闭防火墙即可&#xff01;&#xff01;&#xff01;&#xff01;...

Java设计模式:四、行为型模式-04:中介者模式

文章目录 一、定义&#xff1a;中介者模式二、模拟场景&#xff1a;中介者模式三、违背方案&#xff1a;中介者模式3.1 工程结构3.2 创建数据库3.3 JDBC工具类3.4 单元测试 四、改善代码&#xff1a;中介者模式4.1 工程结构4.2 中介者工程结构图4.3 资源和配置类4.3.1 XML配置对…...

【GO】LGTM_Grafana_Tempo(1)_架构

最近在尝试用 LGTM 来实现 Go 微服务的可观测性&#xff0c;就顺便整理一下文档。 Tempo 会分为 4 篇文章&#xff1a; Tempo 的架构官网测试实操跑通gin 框架发送 trace 数据到 tempogo-zero 微服务框架使用发送数据到 tempo 第一篇是关于&#xff0c;tempo 的架构&#xff…...

MFC 与 QT“常用控件”对比

1、 常用控件 MFC QT 1.静态文本框/标签 CStatic QLabel 按钮 CButton包含了3种样式的按钮&#xff0c;Push Button&#xff0c;Check Box&#xff0c;Radio Box 4种不同的类 2.按钮&#xff1a;推动按钮 Push Button(同一个类CButton) QPushButton 3.按钮&#xf…...

linux 下安装chrome 和 go

1. 安装google-chrome 1.1 首先下载google-chrome.deb安装包 之后 安装 gdebi包 sudo apt install gdebi 1.2 安装所要安装的软件 sudo gdebi code_1.81.1-1691620686_amd64.deb 1.3 解决Chrome无法启动问题 rootubuntu:~/Downloads# whereis google-chrome google-chrome…...

OpenCV: cv2.findContours - ValueError: too many values to unpack

OpenCV找轮廓findContours报错 ValueError: not enough values to unpack (expected 3,got 2) 问题指向这行代码&#x1f447; binary, cnts, hierarchy cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE ) 报错的意思是需要3个返回值但只给了两…...

Vue框架--Vue概述

1.vue概述 Vue是一个渐进式JavaScript 框架,用于动态构建用户界面。 2.vue的特点 (1).遵循MVVM模式 MVVM是Model-View-ViewModel的简写。它本质上就是MVC的改进版 (2).采用组件化模式,提高代码的复用率,且让代码更好的维护。 组件化:简单的说就是使用xxx.vue模式包含一个页面…...

Fiddler安装与使用教程(1) —— 软测大玩家

&#x1f60f;作者简介&#xff1a;博主是一位测试管理者&#xff0c;同时也是一名对外企业兼职讲师。 &#x1f4e1;主页地址&#xff1a;【Austin_zhai】 &#x1f646;目的与景愿&#xff1a;旨在于能帮助更多的测试行业人员提升软硬技能&#xff0c;分享行业相关最新信息。…...

Ubuntu 22.04安装 —— Win11 22H2

目录 Ubuntu使用下载UbuntuVmware 安装图示安装步骤图示 Ubuntu使用 系统环境&#xff1a; Windows 11 22H2Vmware 17 ProUbutun 22.04.3 Server Ubuntu Server documentation | Ubuntu 下载 Ubuntu 官网下载 建议安装长期支持版本 ——> 可以选择桌面版或服务器版(仅包…...

【STM32】IIC的初步使用

IIC简介 物理层 连接多个devices 它是一个支持设备的总线。“总线”指多个设备共用的信号线。在一个 I2C 通讯总线中&#xff0c;可连接多个 I2C 通讯设备&#xff0c;支持多个通讯主机及多个通讯从机。 两根线 一个 I2C 总线只使用两条总线线路&#xff0c;一条双向串行数…...

音视频 ffmpeg命令参数说明

主要参数&#xff1a; -i 设定输入流 -f 设定输出格式(format) -ss 开始时间 -t 时间长度 音频参数&#xff1a; -aframes 设置要输出的音频帧数 -b:a 音频码率 -ar 设定采样率 -ac 设定声音的Channel数 -acodec 设定声音编解码器&#xff0c;如果用copy表示原始编解码数据必须…...

Go学习第十天

打印报错堆栈信息 安装errors包 go get github.com/pkg/errors 具体使用 // 新生成一个错误, 带堆栈信息 func New(message string) error//只附加新的信息 func WithMessage(err error, message string) error//只附加调用堆栈信息 func WithStack(err error) error//同时附…...

pytorch中 nn.Conv2d的简单用法

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride1, padding0, dilation1, groups1, biasTrue,padding_modezeros)参数介绍&#xff1a; in_channels&#xff1a;卷积层输入通道数 out_channels&#xff1a;卷积层输出通道数 kernel_size&#xff1a;卷积层的…...

前端项目工程化之代码规范

目录 一、前言二、ESLint三、Prettier四、项目实战4.1 环境依赖版本4.2 使用pnpm4.3 git提交规范 五、资源 收集六、源码地址 一、前言 前端项目工程化之代码规范是指在前端项目中定义一套代码规范&#xff0c;以确保项目中的代码风格和格式一致&#xff0c;提高代码的可读性和…...

MyBaits Generator

参考文档 MyBatis Generator Core – Introduction to MyBatis Generator MyBatis Generator 详解_enablesubpackages_isea533的博客-CSDN博客 一文解析 MyBatis Generator 的使用及配置 - 掘金 1. Introduction MyBatis Generator (MBG) 是 MyBatis MyBatis的代码生成器。…...

JavaWeb 速通Ajax

目录 一、Ajax快速入门 1.基本介绍 : 2.使用原理 : 二、Ajax经典入门案例 1.需求 : 2.前端页面实现 : 3. 处理HTTP请求的servlet实现 4.引入jar包及druid配置文件、工具类 : 5.Domain层实现 : 6.DAO层实现 : 7.Service层实现 : 8.运行测试 : 三、JQuery操作Ajax 1 …...

vscode c++编译时报错

文章目录 1. 报错内容&#xff1a;GDB Failed with message;2. 报错内容&#xff1a;Unable to start debugging. 1. 报错内容&#xff1a;GDB Failed with message; 例如上图报错&#xff0c;一般就是编译器选择错误&#xff0c;有两种方法解决&#xff1a; 打开 tasks.json …...

基于体系结构架构设计-架构真题(十五)

基于体系结构开发设计&#xff08;Architecture-Base Software Design&#xff09;ABSD&#xff0c;是指构成体系结构的&#xff08;&#xff09;组合驱动&#xff0c;ABSC方法是一个自项向下、递归细化的方法&#xff0c;软件系统的体系结构通过该方法细化&#xff0c;直到能产…...

IPv6网络实验:地址自动生成与全球单播通信探索

文章目录 一、实验背景与目的二、实验拓扑三、实验需求四、实验解法1. 在R1和PC3上开启IPv6链路本地地址自动生成&#xff0c;测试是否能够使用链路本地地址互通2. 为R1配置全球单播地址2001::1/64&#xff0c;使PC3能够自动生成与R1同一网段的IPv6地址3. 测试R1和PC3是否能够使…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

JavaSec-RCE

简介 RCE(Remote Code Execution)&#xff0c;可以分为:命令注入(Command Injection)、代码注入(Code Injection) 代码注入 1.漏洞场景&#xff1a;Groovy代码注入 Groovy是一种基于JVM的动态语言&#xff0c;语法简洁&#xff0c;支持闭包、动态类型和Java互操作性&#xff0c…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

css实现圆环展示百分比,根据值动态展示所占比例

代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

CentOS下的分布式内存计算Spark环境部署

一、Spark 核心架构与应用场景 1.1 分布式计算引擎的核心优势 Spark 是基于内存的分布式计算框架&#xff0c;相比 MapReduce 具有以下核心优势&#xff1a; 内存计算&#xff1a;数据可常驻内存&#xff0c;迭代计算性能提升 10-100 倍&#xff08;文档段落&#xff1a;3-79…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...