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

Flutter中如何自动重启REST API以实时更新应用数据?

在Flutter中自动刷新REST API以获取最新数据的几种方案

嘿,针对你想要确保应用始终获取并更新最新数据的需求,这里有几个在Flutter里实现自动触发API请求的实用方法,每个都附带简单示例:

1. 定时轮询(最直接的方案)

通过Timer.periodic设置固定时间间隔,定期发起API请求。这种方式简单直观,适合数据更新频率可预测的场景。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class AutoRefreshScreen extends StatefulWidget {
  @override
  _AutoRefreshScreenState createState() => _AutoRefreshScreenState();
}

class _AutoRefreshScreenState extends State<AutoRefreshScreen> {
  Timer? _refreshTimer;
  String _latestData = "加载中...";

  @override
  void initState() {
    super.initState();
    // 每10秒刷新一次,可根据需求调整间隔
    _refreshTimer = Timer.periodic(Duration(seconds: 10), (timer) {
      _fetchLatestData();
    });
    // 初始化页面时先请求一次数据
    _fetchLatestData();
  }

  Future<void> _fetchLatestData() async {
    try {
      final response = await http.get(Uri.parse("你的API地址"));
      if (response.statusCode == 200) {
        setState(() {
          _latestData = response.body;
        });
      }
    } catch (e) {
      // 处理请求错误,比如网络异常、API报错等
      print("请求失败: $e");
    }
  }

  @override
  void dispose() {
    // 页面销毁时务必取消定时器,避免内存泄漏
    _refreshTimer?.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text(_latestData)),
    );
  }
}

2. 使用Stream + StreamBuilder

用Stream.periodic创建一个定时流,结合API请求,通过StreamBuilder自动更新UI。这种方式更贴合Flutter的响应式编程思想。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class StreamRefreshScreen extends StatelessWidget {
  // 创建每10秒触发一次的流,自动发起API请求
  Stream<String> _dataStream() {
    return Stream.periodic(Duration(seconds: 10), (_) async {
      final response = await http.get(Uri.parse("你的API地址"));
      if (response.statusCode == 200) {
        return response.body;
      }
      throw Exception("请求失败,请稍后重试");
    }).asyncMap((future) => future);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StreamBuilder<String>(
        stream: _dataStream(),
        initialData: "加载中...",
        builder: (context, snapshot) {
          if (snapshot.hasError) {
            return Center(child: Text("加载失败: ${snapshot.error}"));
          }
          return Center(child: Text(snapshot.data!));
        },
      ),
    );
  }
}

3. 结合状态管理工具(以Riverpod为例)

如果你的应用使用状态管理库,可以把自动刷新逻辑封装在状态里,让整个应用都能共享最新数据,避免重复代码。

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart' as http;

final dataProvider = StateNotifierProvider<DataNotifier, String>((ref) {
  return DataNotifier();
});

class DataNotifier extends StateNotifier<String> {
  Timer? _refreshTimer;

  DataNotifier() : super("加载中...") {
    _startAutoRefresh();
    _fetchData();
  }

  void _startAutoRefresh() {
    _refreshTimer = Timer.periodic(Duration(seconds: 10), (_) {
      _fetchData();
    });
  }

  Future<void> _fetchData() async {
    try {
      final response = await http.get(Uri.parse("你的API地址"));
      if (response.statusCode == 200) {
        state = response.body;
      }
    } catch (e) {
      print("请求失败: $e");
    }
  }

  @override
  void dispose() {
    _refreshTimer?.cancel();
    super.dispose();
  }
}

// 使用该状态的页面
class RiverpodRefreshScreen extends ConsumerWidget {
  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final data = ref.watch(dataProvider);
    return Scaffold(
      body: Center(child: Text(data)),
    );
  }
}

4. 监听应用生命周期(后台切前台时刷新)

除了定时轮询,还可以在应用从后台回到前台时自动刷新数据,避免后台不必要的请求,同时保证前台时数据最新。

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class LifecycleRefreshScreen extends StatefulWidget {
  @override
  _LifecycleRefreshScreenState createState() => _LifecycleRefreshScreenState();
}

class _LifecycleRefreshScreenState extends State<LifecycleRefreshScreen> with WidgetsBindingObserver {
  String _latestData = "加载中...";

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this);
    _fetchLatestData();
  }

  Future<void> _fetchLatestData() async {
    try {
      final response = await http.get(Uri.parse("你的API地址"));
      if (response.statusCode == 200) {
        setState(() {
          _latestData = response.body;
        });
      }
    } catch (e) {
      print("请求失败: $e");
    }
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    // 当应用从后台回到前台时触发刷新
    if (state == AppLifecycleState.resumed) {
      _fetchLatestData();
    }
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(child: Text(_latestData)),
    );
  }
}

一些最佳实践提醒

  • 控制刷新频率:根据数据更新的实际需求设置间隔,不要过于频繁,避免消耗过多流量和电量。
  • 错误处理与重试:请求失败时可以添加指数退避重试机制,比如第一次等5秒,第二次等10秒,避免一直重复失败请求。
  • 缓存策略:可以结合本地缓存(比如shared_preferences或Hive),请求失败时先展示缓存数据,后台再尝试刷新,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 07:17:44