1. 添加依赖
首先在pubspec.yaml
中添加http
包:
dependencies:
flutter:
sdk: flutter
http: ^1.1.0 # 网络请求库
然后运行flutter pub get
来获取依赖包。
2. 创建 API 服务类
创建一个专门的类来处理所有 API 请求,方便统一管理。
import 'dart:convert'; // 用于JSON编解码
import 'package:http/http.dart' as http; // HTTP请求库
class ApiService {
// API基础URL(替换为你的API地址)
final String baseUrl = 'https://api.example.com';
// 添加headers,如认证token
Map<String, String> get headers => {
'Content-Type': 'application/json',
// 'Authorization': 'Bearer your_token_here', // 如果需要认证
};
// GET请求示例(获取数据列表)
Future<List<dynamic>> fetchDataList() async {
try {
// 构建请求URL
final url = Uri.parse('$baseUrl/data');
// 发送GET请求
final response = await http.get(url, headers: headers);
// 检查响应状态码
if (response.statusCode == 200) {
// 请求成功,解析JSON数据
return json.decode(response.body);
} else {
// 请求失败,抛出错误
throw Exception('请求失败: ${response.statusCode}');
}
} catch (e) {
// 处理异常
print('API请求错误: $e');
rethrow;
}
}
// POST请求示例(提交数据)
Future<Map<String, dynamic>> createData(Map<String, dynamic> data) async {
try {
// 构建请求URL
final url = Uri.parse('$baseUrl/data');
// 发送POST请求,附带JSON数据
final response = await http.post(
url,
headers: headers,
body: json.encode(data), // 将Map转为JSON字符串
);
// 检查响应状态码
if (response.statusCode == 201) {
// 创建成功,解析返回的JSON数据
return json.decode(response.body);
} else {
// 请求失败,抛出错误
throw Exception('创建失败: ${response.statusCode}');
}
} catch (e) {
// 处理异常
print('API请求错误: $e');
rethrow;
}
}
}
异步编程 vs 同步编程
- 同步编程:代码按顺序执行,每个操作必须等待前一个操作完成后才能开始。如果某个操作耗时较长(如网络请求),整个程序会被阻塞。
- 异步编程:当程序发起一个耗时操作时,它不会等待该操作完成,而是继续执行后续代码。当操作完成后,通过回调、Promise、Future 等机制通知程序处理结果。
Future
是异步编程中的一个核心概念,它代表一个异步操作的结果占位符。简单来说,Future
表示一个尚未完成但将来会完成的操作,它有三种状态:
- 未完成(pending):操作正在进行中,结果尚未就绪。
- 已完成(completed):操作成功完成,返回结果。
- 已失败(failed):操作执行失败,返回错误。
使用 Future 的基本操作
// 创建一个返回Future的异步函数
Future<String> fetchData() async {
// 模拟一个耗时2秒的操作
await Future.delayed(Duration(seconds: 2));
return "操作完成";
}
void main() {
print("开始执行");
// 调用异步函数,立即返回一个Future,不会阻塞后续代码
Future<String> future = fetchData();
// 注册回调处理结果
future.then((result) {
print("结果: $result");
}).catchError((error) {
print("错误: $error");
}).whenComplete(() {
print("操作结束,无论成功或失败都会执行");
});
print("继续执行其他任务...");
}
// 输出顺序:
// 开始执行
// 继续执行其他任务...
// (2秒后)
// 结果: 操作完成
// 操作结束,无论成功或失败都会执行
调用这个的代码
import 'dart:convert';
import 'package:http/http.dart' as http;
void main() async {
// 实例化 ApiService 类
final apiService = ApiService();
// 调用 fetchDataList 方法获取数据列表
try {
print('正在获取数据列表...');
final dataList = await apiService.fetchDataList();
print('数据列表获取成功,共 ${dataList.length} 条数据');
print('数据内容:$dataList');
} catch (e) {
print('获取数据列表失败: $e');
}
// 调用 createData 方法提交数据
try {
print('\n正在提交数据...');
final newData = {
'name': '示例数据',
'description': '这是一个测试数据',
'createdAt': DateTime.now().toIso8601String(),
};
final response = await apiService.createData(newData);
print('数据提交成功,返回结果:$response');
} catch (e) {
print('提交数据失败: $e');
}
}
// ApiService 类保持不变
class ApiService {
// API基础URL(替换为你的API地址)
final String baseUrl = 'https://api.example.com';
// 添加headers,如认证token
Map<String, String> get headers => {
'Content-Type': 'application/json',
// 'Authorization': 'Bearer your_token_here', // 如果需要认证
};
// GET请求示例(获取数据列表)
Future<List<dynamic>> fetchDataList() async {
try {
// 构建请求URL
final url = Uri.parse('$baseUrl/data');
// 发送GET请求
final response = await http.get(url, headers: headers);
// 检查响应状态码
if (response.statusCode == 200) {
// 请求成功,解析JSON数据
return json.decode(response.body);
} else {
// 请求失败,抛出错误
throw Exception('请求失败: ${response.statusCode}');
}
} catch (e) {
// 处理异常
print('API请求错误: $e');
rethrow;
}
}
// POST请求示例(提交数据)
Future<Map<String, dynamic>> createData(Map<String, dynamic> data) async {
try {
// 构建请求URL
final url = Uri.parse('$baseUrl/data');
// 发送POST请求,附带JSON数据
final response = await http.post(
url,
headers: headers,
body: json.encode(data), // 将Map转为JSON字符串
);
// 检查响应状态码
if (response.statusCode == 201) {
// 创建成功,解析返回的JSON数据
return json.decode(response.body);
} else {
// 请求失败,抛出错误
throw Exception('创建失败: ${response.statusCode}');
}
} catch (e) {
// 处理异常
print('API请求错误: $e');
rethrow;
}
}
}
在 UI 中使用 API 服务
以下是一个简单的 StatefulWidget 示例,展示如何在 UI 中调用上述 API 方法:
import 'package:flutter/material.dart';
class ApiExampleScreen extends StatefulWidget {
@override
_ApiExampleScreenState createState() => _ApiExampleScreenState();
}
class _ApiExampleScreenState extends State<ApiExampleScreen> {
final ApiService _apiService = ApiService(); // 实例化API服务
List<dynamic> _dataList = []; // 存储API返回的数据
bool _isLoading = false; // 加载状态
String? _errorMessage; // 错误信息
@override
void initState() {
super.initState();
_fetchData(); // 页面加载时获取数据
}
// 获取数据方法
Future<void> _fetchData() async {
setState(() {
_isLoading = true; // 开始加载,显示加载状态
_errorMessage = null; // 清除之前的错误信息
});
try {
// 调用API服务的GET方法
final data = await _apiService.fetchDataList();
// 更新UI状态
setState(() {
_dataList = data; // 存储获取的数据
_isLoading = false; // 加载完成
});
} catch (e) {
// 处理异常
setState(() {
_errorMessage = e.toString(); // 显示错误信息
_isLoading = false; // 加载完成
});
}
}
// 创建数据方法
Future<void> _createData() async {
// 准备要提交的数据
final newData = {
'name': '新数据',
'description': '这是一个示例数据',
'created_at': DateTime.now().toIso8601String(),
};
setState(() {
_isLoading = true;
_errorMessage = null;
});
try {
// 调用API服务的POST方法
final response = await _apiService.createData(newData);
// 更新UI状态
setState(() {
_dataList.add(response); // 将新数据添加到列表
_isLoading = false;
});
// 显示成功提示
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('数据创建成功'))
);
} catch (e) {
// 处理异常
setState(() {
_errorMessage = e.toString();
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('API示例'),
),
body: Center(
child: _isLoading
? CircularProgressIndicator() // 显示加载中
: _errorMessage != null
? Text('错误: $_errorMessage') // 显示错误信息
: _dataList.isEmpty
? Text('暂无数据') // 数据为空
: ListView.builder( // 显示数据列表
itemCount: _dataList.length,
itemBuilder: (context, index) {
final item = _dataList[index];
return ListTile(
title: Text(item['name'] ?? '无名称'),
subtitle: Text(item['description'] ?? ''),
);
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: _createData, // 点击按钮创建数据
child: Icon(Icons.add),
),
);
}
}
处理 JSON 序列化
对于复杂的数据模型,建议创建对应的 Dart 类并实现序列化方法:
// 数据模型类示例
class DataItem {
final String id;
final String name;
final String description;
final DateTime createdAt;
DataItem({
required this.id,
required this.name,
required this.description,
required this.createdAt,
});
// 工厂方法:从JSON数据创建对象
factory DataItem.fromJson(Map<String, dynamic> json) {
return DataItem(
id: json['id'] ?? '',
name: json['name'] ?? '',
description: json['description'] ?? '',
createdAt: DateTime.parse(json['created_at']),
);
}
// 将对象转为JSON
Map<String, dynamic> toJson() {
return {
'id': id,
'name': name,
'description': description,
'created_at': createdAt.toIso8601String(),
};
}
}
// 然后在API服务中使用模型类
Future<List<DataItem>> fetchDataList() async {
final response = await http.get(Uri.parse('$baseUrl/data'));
if (response.statusCode == 200) {
// 将JSON数组转换为对象列表
return (json.decode(response.body) as List)
.map((item) => DataItem.fromJson(item))
.toList();
} else {
throw Exception('请求失败');
}
}