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

Flutter Riverpod实现:每5秒重复调用API并更新界面

解决方案:实现Riverpod定时刷新API数据

1. 为FutureProvider添加定时刷新逻辑

在dataProvider中,通过Timer.periodic实现每5秒触发一次数据刷新,同时利用ref.onDispose清理定时器避免内存泄漏:

final dataProvider = FutureProvider<String>((ref) async {
  // 每5秒触发一次Provider刷新
  final timer = Timer.periodic(const Duration(seconds: 5), (_) {
    ref.invalidateSelf(); // 触发Provider重新执行数据获取逻辑
  });

  // 当Provider不再被监听时,销毁定时器
  ref.onDispose(() => timer.cancel());

  // 调用API获取数据
  return ref.watch(dataService).getData();
});

2. 优化UI层的异步状态处理

原代码直接将异步结果转为字符串显示,无法区分加载、错误、成功状态,建议用AsyncValue.when方法处理不同状态:

class MyExampleApp extends ConsumerWidget {
  const MyExampleApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final dataAsync = ref.watch(dataProvider);

    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: dataAsync.when(
            loading: () => const CircularProgressIndicator(), // 加载中显示进度条
            error: (error, _) => Text('加载失败: $error'), // 错误状态显示错误信息
            data: (data) => Text(data), // 成功状态显示数据
          ),
        ),
      ),
    );
  }
}

3. 可选优化:返回结构化数据(推荐)

原getData方法返回字符串,建议解析为结构化模型,让UI层更易处理:

// 定义Post数据模型
class Post {
  final int userId;
  final int id;
  final String title;
  final String body;

  Post({required this.userId, required this.id, required this.title, required this.body});

  factory Post.fromJson(Map<String, dynamic> json) {
    return Post(
      userId: json['userId'],
      id: json['id'],
      title: json['title'],
      body: json['body'],
    );
  }
}

// 修改DataService的getData方法
class DataService {
  final Dio _dio = Dio();

  Future<List<Post>> getData() async {
    try {
      final response = await _dio.get("https://jsonplaceholder.typicode.com/posts");
      return (response.data as List).map((json) => Post.fromJson(json)).toList();
    } on SocketException {
      throw Exception("网络连接异常");
    } catch (e) {
      throw Exception(e.toString());
    }
  }
}

// 更新Provider泛型类型
final dataProvider = FutureProvider<List<Post>>((ref) async {
  final timer = Timer.periodic(const Duration(seconds: 5), (_) {
    ref.invalidateSelf();
  });
  ref.onDispose(() => timer.cancel());
  return ref.watch(dataService).getData();
});

// UI层改为列表展示
data: (posts) => ListView.builder(
  itemCount: posts.length,
  itemBuilder: (context, index) {
    final post = posts[index];
    return ListTile(
      title: Text(post.title),
      subtitle: Text(post.body),
    );
  },
),

核心逻辑说明

  • ref.invalidateSelf():触发FutureProvider重新执行数据获取逻辑,从而拉取最新数据。
  • ref.onDispose:确保组件销毁时定时器被取消,避免内存泄漏。
  • AsyncValue.when:统一处理异步状态的三种场景,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:22:58