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

Flutter调用API获取数据后如何保存到SharedPreferences?

Flutter登录返回用户数据持久化到SharedPreferences实现方案

前置准备

  • 首先在项目pubspec.yaml中添加SharedPreferences依赖,执行flutter pub get完成安装:
dependencies:
  flutter:
    sdk: flutter
  shared_preferences: ^2.2.2

注:版本号可替换为pub平台的最新稳定版本,插件内部已做全平台兼容,无需额外配置原生端权限。

封装本地存储工具类

为避免各处重复编写存储逻辑,统一封装操作方法。由于SharedPreferences仅支持存储基础类型、字符串、字符串列表,存储结构化用户数据时需要先转成JSON字符串:

import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';

class SPUtil {
  // 定义存储key常量,避免硬编码写错
  static const String _userInfoKey = "cached_user_info";
  static const String _loginFlagKey = "is_logged_in";

  // 保存全量用户信息
  static Future<void> cacheUserInfo(Map<String, dynamic> userData) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString(_userInfoKey, jsonEncode(userData));
    await prefs.setBool(_loginFlagKey, true);
  }

  // 读取本地缓存的用户信息
  static Future<Map<String, dynamic>?> getCachedUserInfo() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    final String? userJsonStr = prefs.getString(_userInfoKey);
    if (userJsonStr == null || userJsonStr.isEmpty) return null;
    return jsonDecode(userJsonStr) as Map<String, dynamic>;
  }

  // 退出登录时清除本地用户缓存
  static Future<void> clearUserCache() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.remove(_userInfoKey);
    await prefs.setBool(_loginFlagKey, false);
  }

  // 按需单独存储高频使用字段,比如用户ID
  static Future<void> cacheUserId(String userId) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    await prefs.setString("cached_user_id", userId);
  }

  static Future<String?> getCachedUserId() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    return prefs.getString("cached_user_id");
  }
}

修改现有登录逻辑

在原有登录校验通过的分支里,页面跳转前插入存储逻辑即可,修改后的登录方法代码如下:

Future<Loginmodel?> login() async {
  if (passwordController.text.isNotEmpty && nameController.text.isNotEmpty) {
    var response = await http.post(
        Uri.parse('XYZ'),
        headers: {"Content-Type": "application/json"},
        body: jsonEncode({
          'UserName': nameController.text,
          'Password': passwordController.text,
          'DeviceToken': '',
          'DeviceType': ''
        })
    );
    if (response.statusCode == 200) {
      var data = jsonDecode(response.body);
      if (data['data']['UserID'] == null) {
        ScaffoldMessenger.of(context)
            .showSnackBar(const SnackBar(content: Text("账号或密码错误")));
      } else {
        // 校验通过后先持久化用户数据,必须加await等待存储完成
        await SPUtil.cacheUserInfo(data['data']);
        await SPUtil.cacheUserId(data['data']['UserID'].toString());

        // 存储完成后再做跳转和提示
        if (context.mounted) {
          Navigator.push(
              context, MaterialPageRoute(builder: (context) => const Homescreen())
          );
          ScaffoldMessenger.of(context)
              .showSnackBar(const SnackBar(content: Text("登录成功")));
        }
      }
    }
  } else {
    ScaffoldMessenger.of(context)
        .showSnackBar(const SnackBar(content: Text("输入框不能为空")));
  }
  return null;
}

读取缓存示例

后续业务中需要用到用户信息时,直接调用封装好的方法即可:

// 比如首页初始化时读取本地用户信息
@override
void initState() {
  super.initState();
  loadLocalUserInfo();
}

void loadLocalUserInfo() async {
  Map<String, dynamic>? userInfo = await SPUtil.getCachedUserInfo();
  if (userInfo != null) {
    print("用户名:${userInfo['UserName']}");
    print("手机号:${userInfo['MobileNo']}");
    print("邮箱:${userInfo['Email']}");
  }
}

注意点

  • 所有SharedPreferences的写入操作都是异步的,必须加await等待执行完成,否则可能出现跳转页面后读取不到刚存数据的问题
  • 不要把密码、支付密钥这类高敏感信息存在SharedPreferences中,普通用户资料、登录状态这类非敏感数据存储没有问题
  • 页面跳转前建议加context.mounted判断,避免异步操作完成后组件已经销毁导致的报错
  • 退出登录时一定要调用SPUtil.clearUserCache()清除本地缓存,避免多账号切换时数据混乱

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 18:54:25