网络请求与数据存储
更换镜像源
通过环境变量配置国内镜像源,以下是具体实现方法及注意事项:
国内镜像源需通过设置以下两个环境变量实现:
PUB_HOSTED_URL
:指定 Dart 包仓库镜像地址FLUTTER_STORAGE_BASE_URL
:指定 Flutter SDK 和依赖的镜像地址
常用镜像源列表(任选其一):
清华大学 TUNA 协会
bash
export PUB_HOSTED_URL=https://mirrors.tuna.tsinghua.edu.cn/dart-pub
export FLUTTER_STORAGE_BASE_URL=https://mirrors.tuna.tsinghua.edu.cn/flutter
上海交大 SJTUG
bash
export PUB_HOSTED_URL=https://dart-pub.mirrors.sjtug.sjtu.edu.cn
export FLUTTER_STORAGE_BASE_URL=https://mirrors.sjtug.sjtu.edu.cn
阿里云
bash
export PUB_HOSTED_URL=https://mirrors.aliyun.com/dart-pub
export FLUTTER_STORAGE_BASE_URL=https://mirrors.aliyun.com/flutter
Flutter 社区主镜像
bash
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
以 Mac 为例,将 export
命令添加到 ~/.bashrc
、~/.zshrc
或 ~/.profile
文件末尾,执行 source ~/.bashrc
或 source ~/.zshrc
或 source ~/.profile
生效。
执行以下命令后,观察下载速度是否提升,或通过日志检查是否命中镜像地址:flutter pub get
通过 HTTP 请求获取网络数据
通过 HTTP 请求获取网络数据,将数据渲染到页面上,需要使用 http
包。
dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class HttpStudy extends StatefulWidget {
const HttpStudy({super.key});
@override
State<HttpStudy> createState() => _HttpStudyState();
}
class _HttpStudyState extends State<HttpStudy> {
var resultShow = "";
var resultShow2 = "";
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('基于HTTP实现网络操作-Flutter网络开发实战应用'),
),
body: Column(
children: [
_doGetBtn(),
_doPostBtn(),
_doPostJsonBtn(),
Text('返回的结果: $resultShow'),
Text('解析的Msg: $resultShow2'),
],
),
);
}
_doGetBtn() {
return ElevatedButton(onPressed: _doGet, child: const Text('发送Get请求'));
}
_doPostBtn() {
return ElevatedButton(onPressed: _doPost, child: const Text('发送Post请求'));
}
_doPostJsonBtn() {
return ElevatedButton(
onPressed: _doPostJson, child: const Text('发送Post请求'));
}
/// 发送Get请求
void _doGet() async {
var uri =
Uri.parse('https://api.geekailab.com/uapi/test/test?requestPrams=11');
var response = await http.get(uri);
if (response.statusCode == 200) {
setState(() {
resultShow = response.body;
});
} else {
setState(() {
resultShow = '请求失败: code:${response.statusCode}, body${response.body}';
});
}
}
/// 发送Post请求
void _doPost() async {
var uri =
Uri.parse('https://api.geekailab.com/uapi/test/test?requestParams=11');
var params = {"requestParams": "doPost"};
print("params:${params}");
/// 数据格式要求为Map<string, string>
var response = await http.post(uri, body: params);
if (response.statusCode == 200) {
setState(() {
resultShow = response.body;
});
} else {
setState(() {
resultShow = '请求失败: code:${response.statusCode}, body${response.body}';
});
}
}
/// 发送Json类型的Post请求
_doPostJson() async {
var uri = Uri.parse('https://api.geekailab.com/uapi/test/testJson');
var params = {"requestParams": "doPost"};
var response = await http.post(
uri,
body: jsonEncode(params), /// Map转JSON字符串
headers: {"content-type": "application/json"}, /// 设置请求头
);
if (response.statusCode == 200) {
setState(() {
resultShow = response.body;
});
/// 将Json字符串转为Map类型
var map = jsonDecode(response.body);
setState(() {
resultShow2 = map['msg'];
});
} else {
setState(() {
resultShow = '请求失败: code:${response.statusCode}, body${response.body}';
});
}
}
}
将Json字符串转换为 Map 和 Model
- 将Json字符串转换为Map:利用
jsonDecode
方法将Json字符串转换为Map - 将Map转换为Json字符串:利用
jsonEncode
方法将Map转换为Json字符串 - 将Map转换为Dart Model实体类:利用
fromJson
方法将Map转换为Dart Model实体类- 可以利用 Json转Dart Model 工具将Json字符串转换为Dart Model实体类。
dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_next_storage/dart_model.dart';
/// JSON解析与Dart Model 的使用
class JsonParsingPage extends StatefulWidget {
const JsonParsingPage({super.key});
@override
State<JsonParsingPage> createState() => _JsonParsingPageState();
}
class _JsonParsingPageState extends State<JsonParsingPage> {
var resultShow = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("JSON解析与Dart Model 的使用")),
body: Column(
children: [_json2MapBtn(), _json2ModelBtn(), Text('结果:${resultShow}')],
),
);
}
_json2MapBtn() {
return ElevatedButton(onPressed: _json2Map, child: const Text("Json转Map"));
}
_json2ModelBtn() {
return ElevatedButton(
onPressed: _json2Model, child: const Text("Json转Model实体类"));
}
void _json2Map() {
var jsonString =
'{"code":0,"data":{"code":0,"method":"GET","requestPrams":"11"},"msg":"SUCCESS."}';
Map<String, dynamic> map = jsonDecode(jsonString);
setState(() {
resultShow =
"code:${map['code']} jsonParams: ${map['data']['requestPrams']}";
});
}
void _json2Model() {
var jsonString =
'{"code":200,"data":{"code":0,"method":"GET","requestPrams":"11"},"msg":"SUCCESS."}';
/// 将Json转成Map
Map<String, dynamic> map = jsonDecode(jsonString);
/// 将Map转成Dart Model实体类
DataModel dataModel = DataModel.fromJson(map);
setState(() {
resultShow =
'code:${dataModel.code}; requestPrams:${dataModel.data?.requestPrams}';
});
}
}
FutureBuilder 的使用
FutureBuilder 是 Flutter 中用于处理异步操作的组件,它可以帮助我们在异步操作完成之前显示一个加载状态,并在异步操作完成后更新UI。
dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_next_storage/dart_model.dart';
import 'package:http/http.dart' as http;
class FutureStudy extends StatefulWidget {
const FutureStudy({super.key});
@override
State<FutureStudy> createState() => _FutureStudyState();
}
class _FutureStudyState extends State<FutureStudy> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Future与FutureBuilder实战应用')),
body: FutureBuilder<DataModel>(
future: fetchGet(),
builder: (BuildContext context, AsyncSnapshot<DataModel> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.none:
return const Text('state none');
case ConnectionState.waiting:
return const Center(
child: CircularProgressIndicator(),
);
case ConnectionState.active:
return const Text('state active');
case ConnectionState.done:
if (snapshot.hasError) {
return Text(
'${snapshot.error}',
style: const TextStyle(color: Colors.red),
);
} else {
print('snapshot.data${snapshot.data}');
return Column(
children: [
Text('code:${snapshot.data?.code}'),
Text('requestParams:${snapshot.data?.data?.requestPrams}')
],
);
}
}
},
),
);
}
Future<DataModel> fetchGet() async {
var uri =
Uri.parse('https://api.geekailab.com/uapi/test/test?requestPrams=11');
final response = await http.get(uri);
var result = jsonDecode(response.body);
return DataModel.fromJson(result);
}
}
shared_preferences
的使用
shared_preferences
是 Flutter 中用于存储和读取简单数据(如字符串、整数、浮点数等)的库。它提供了一个简单的键值对存储系统,可以用于保存和检索应用程序的配置数据。
首先在 pubspec.yaml
文件中添加包声明,然后执行 flutter pub get
命令。
yaml
dependencies:
shared_preferences: ^2.2.3
常用的API:
SharedPreferences.getInstance()
:获取SharedPreferences
实例setInt
:设置整数类型的值getInt
:获取整数类型的值setString
:设置字符串类型的值getString
:获取字符串类型的值
dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class SharedPreferencesStudy extends StatefulWidget {
const SharedPreferencesStudy({super.key});
@override
State<SharedPreferencesStudy> createState() => _SharedPreferencesStudyState();
}
class _SharedPreferencesStudyState extends State<SharedPreferencesStudy> {
String countString = '';
String localCount = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('基于shared_perferences实现计数器')),
body: Column(
children: [
ElevatedButton(
onPressed: _incrementCounter,
child: const Text('Increment Counter')),
ElevatedButton(
onPressed: _getCounter, child: const Text('Get Counter')),
Text(
countString,
style: const TextStyle(fontSize: 20),
),
Text(
"result:${localCount}",
style: const TextStyle(fontSize: 20),
)
],
),
);
}
void _incrementCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
countString = "$countString 1";
});
int counter = (prefs.getInt('counter') ?? 0) + 1;
await prefs.setInt('counter', counter);
}
_getCounter() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
localCount = prefs.getInt('counter').toString();
});
}
}