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

Flutter启动页API存入SharedPreferences时卡顿无法跳转求助

解决Flutter启动页API数据存储卡顿问题

问题分析

启动页调用API获取64组键值对,存储到SharedPreferences时执行到第47组卡顿,无法跳转至下一页,控制台出现W/ratelimit( 9649): Single process limit 250/s drop 102 lines.警告,核心问题在于异步逻辑处理错误、循环越界和SharedPreferences操作效率低下。

修复步骤

1. 修正API调用的异步等待逻辑

原代码中调用provider.fetchGeneralSetting()时未使用await,导致还未获取到API数据就开始执行存储逻辑,且重复调用了fetchGeneralSetting(),造成不必要的重复请求。修改如下:

api() async {
  final provider = Provider.of<GeneralSettingProvider>(context, listen: false);
  // 等待API请求完成
  await provider.fetchGeneralSetting();

  if (provider.generalSettingModel?.result != null) {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    Map<String, String> settingsMap = {};
    // 批量整理键值对
    for (int i = 0; i < provider.generalSettingModel!.result!.length; i++) {
      final key = provider.generalSettingModel!.result![i].key ?? '';
      final value = provider.generalSettingModel!.result![i].value ?? '';
      if (key.isNotEmpty) {
        settingsMap[key] = value;
      }
    }
    // 批量存储到SharedPreferences
    await prefs.setStringMap(settingsMap);
    // 确保页面未销毁再跳转
    if (mounted) {
      Navigator.pushReplacement(context,
          MaterialPageRoute(builder: (context) => const BottomMenuBar()));
    }
  }
}

2. 修复循环越界问题

原循环条件i <= provider.generalSettingModel!.result!.length会导致索引超出数组范围(数组索引从0开始,最大索引为length-1),改为i < provider.generalSettingModel!.result!.length避免数组越界错误。

3. 优化SharedPreferences存储效率

原代码循环中多次调用setString,每次都是独立的异步IO操作,会导致性能瓶颈。改为先将所有键值对存入Map,再通过setStringMap一次性批量存储,大幅减少IO操作次数。

4. 避免build方法中重复执行日志输出

原build方法中每次都会调用getdata(),而build会频繁触发,导致大量重复日志输出,甚至触发日志速率限制。可以移除getdata()方法,改用Consumer监听Provider状态变化:

@override
Widget build(BuildContext context) {
  return Consumer<GeneralSettingProvider>(
    builder: (context, provider, child) {
      if (provider.loading) {
        debugPrint("===>> Loading...");
      } else if (provider.generalSettingModel != null) {
        debugPrint("===>> ${provider.generalSettingModel!.status}");
      }
      return const Scaffold(
        body: SingleChildScrollView(
          child: Column(
            children: [
              Image(image: AssetImage('assets/images/splash-img.png')),
            ],
          ),
        ),
      );
    },
  );
}

5. 完善Provider的错误处理(可选)

在Provider的fetchGeneralSetting中添加错误捕获,避免API请求失败导致后续逻辑阻塞:

fetchGeneralSetting() async {
  _loading = true;
  notifyListeners();
  try {
    generalSettingModel = await ApiService().generalSetting();
    errorMessage = null;
  } catch (e) {
    errorMessage = e.toString();
    if (kDebugMode) {
      print("API请求失败: $e");
    }
  } finally {
    _loading = false;
    notifyListeners();
  }
}

关于日志速率限制警告

W/ratelimit...是因为调试日志输出频率超过了系统的单进程日志速率限制(250条/秒),修复上述问题后,日志输出会恢复正常,该警告也会消失。

内容的提问来源于stack exchange,提问作者Himanshu M. Dave

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 02:17:04