Flutter请求Reddit JSON数据失败,FutureBuilder报错求助
问题排查与解决方法
一、直接触发报错的原因
在FutureBuilder的错误分支中,你使用了return throw Exception();,这是语法错误——throw不能作为返回值直接使用,会直接抛出未捕获的异常,导致你看到的错误日志。
二、JSON序列化结构不匹配Reddit API返回
Reddit的API返回结构和你的序列化类完全不符:
- API最外层是包含
data字段的对象,data内部才有children数组 - 每个
children元素的data是单个帖子对象,而非List - 字段类型不匹配:
ups是整数类型,不是String
这会导致反序列化失败,触发FutureBuilder的错误分支。
三、ListTile数据引用错误
你写的${snapshot.data?.children[index].data[index].title}是错误的,每个children的data是单个Post对象,不是数组,不需要再用[index]索引。
修正后的序列化类
import 'package:json_annotation/json_annotation.dart'; part 'post_model.g.dart'; @JsonSerializable() class RedditResponse { final RedditData data; RedditResponse({required this.data}); factory RedditResponse.fromJson(Map<String, dynamic> json) => _$RedditResponseFromJson(json); } @JsonSerializable() class RedditData { final List<PostWrapper> children; RedditData({required this.children}); factory RedditData.fromJson(Map<String, dynamic> json) => _$RedditDataFromJson(json); } @JsonSerializable() class PostWrapper { final Post data; PostWrapper({required this.data}); factory PostWrapper.fromJson(Map<String, dynamic> json) => _$PostWrapperFromJson(json); } @JsonSerializable() class Post { final String title; final String? thumbnail; final int ups; final String? selftext; Post({required this.title, this.thumbnail, required this.ups, this.selftext}); factory Post.fromJson(Map<String, dynamic> json) => _$PostFromJson(json); }
修正后的HomePage及FutureBuilder代码
class _MyHomePageState extends State<MyHomePage> { late Future<RedditResponse> postsResponse; @override void initState() { super.initState(); postsResponse = getPostsList(); } @override Widget build(BuildContext context) { return Scaffold( body: FutureBuilder<RedditResponse>( future: postsResponse, builder: (context, snapshot) { if (snapshot.hasData) { final posts = snapshot.data!.data.children; return ListView.builder( itemCount: posts.length, itemBuilder: (context, index) { final post = posts[index].data; return Card( child: ListTile( title: Text(post.title), subtitle: post.selftext?.isNotEmpty == true ? Text(post.selftext!) : null, leading: post.thumbnail != null && !['self', 'default'].contains(post.thumbnail) ? Image.network(post.thumbnail!) : const Icon(Icons.article), ), ); }); } else if (snapshot.hasError) { return Center(child: Text('加载失败: ${snapshot.error}')); } return const Center(child: CircularProgressIndicator()); }, ), ); } } Future<RedditResponse> getPostsList() async { const url = 'https://reddit.com/r/flutterdev/new.json'; final response = await http.get(Uri.parse(url)); print('Status code: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}'); if (response.statusCode == 200) { return RedditResponse.fromJson(json.decode(response.body)); } else { throw Exception('Error: ${response.reasonPhrase}'); } }
额外注意事项
- 运行
flutter pub run build_runner build生成序列化所需的.g.dart文件 - 处理
thumbnail的特殊值(如'self'、'default'),避免图片加载异常 - 空值判断要严谨,防止出现空指针异常
内容的提问来源于stack exchange,提问作者moran020
相关产品推荐
相关产品推荐

