You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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}');
  }
}

额外注意事项

  1. 运行flutter pub run build_runner build生成序列化所需的.g.dart文件
  2. 处理thumbnail的特殊值(如'self'、'default'),避免图片加载异常
  3. 空值判断要严谨,防止出现空指针异常

内容的提问来源于stack exchange,提问作者moran020

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 20:50:30