Flutter中如何避免数据缺失引发崩溃并捕获异常
解决网络请求崩溃并显示错误信息的方案
你的代码存在多个未处理的异常场景(如网络连接失败、JSON解析错误、索引越界、字段为空等),以下是针对性的修复方案,确保应用不会崩溃并在界面上展示错误信息。
修改后的网络请求函数
Future<SCoin?> fetchCoinData(int giveMeIndex) async { try { final response = await http.get(Uri.parse(url)); // 处理非200状态码 if (response.statusCode != 200) { throw Exception('请求失败,状态码: ${response.statusCode}'); } final jsonresponse = json.decode(response.body); // 校验返回数据格式是否为数组 if (jsonresponse is! List) { throw Exception('返回数据格式错误,预期为数组类型'); } // 检查索引是否在合法范围内 if (giveMeIndex < 0 || giveMeIndex >= jsonresponse.length) { throw Exception('索引越界,当前数据长度: ${jsonresponse.length}'); } coins.clear(); // 避免重复累加数据 for (var i in jsonresponse) { // 为可能为空的字段设置默认值 var coinItem = SCoin( name: i['name'] ?? '未知名称', image: i['image'] ?? '', current_price: i['current_price'] ?? 0.0); coins.add(coinItem); } return SCoin.fromJson(jsonresponse[giveMeIndex]); } catch (e) { // 捕获所有异常并抛出,交由FutureBuilder处理 throw Exception('获取数据失败: $e'); } }
修改后的FutureBuilder组件
FutureBuilder<SCoin?>( future: fetchCoinData(2), builder: (context, snapshot) { // 处理加载状态 if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 数据加载成功 if (snapshot.hasData && snapshot.data != null) { return Column( children: [ Container( width: 45, height: 45, child: Image.network( snapshot.data!.image, // 图片加载失败时显示错误图标 errorBuilder: (context, error, stackTrace) { return const Icon(Icons.error_outline); }, ), ), Text(snapshot.data!.name), Text(snapshot.data!.current_price.toString()) ], ); } // 加载失败显示错误信息 else if (snapshot.hasError) { return Text('错误提示: ${snapshot.error}'); } // 无数据且无错误的兜底情况 return const Text('暂无数据'); }, ),
核心改进点
- 全局异常捕获: 用
try-catch包裹整个请求逻辑,覆盖网络错误、解析错误、索引越界等所有异常场景,避免应用崩溃。 - 数据合法性校验: 检查响应状态码、返回数据格式、索引范围,从源头避免无效操作。
- 空值安全处理: 为JSON字段设置默认值,防止构造
SCoin时出现空指针错误。 - 图片错误处理: 给
Image.network添加errorBuilder,图片加载失败时显示友好提示而非崩溃。 - 状态逻辑清晰: 明确区分加载、成功、失败、无数据四种状态,界面展示更合理。
内容的提问来源于stack exchange,提问作者mary
相关产品推荐
相关产品推荐

