GetxService的特点
生命周期贯穿整个应用(一般
Get.putAsync后常驻内存)。适合存放 运行时全局状态(比如用户登录信息、配置开关、主题模式)。
但 数据只存在内存,应用关闭后会丢失。
运行时常驻:只要应用还在前台/后台运行,
GetxService实例会一直存在,不会像普通Controller那样被回收。应用被完全杀死/重启:所有内存数据(包括
GetxService中的字段)都会丢失。
SharedPreferences的特点
用于本地持久化存储,数据即使关闭应用也能保存。
但它是 键值对存储工具,不负责状态管理。
适合放在 GetxService 的数据
特点:运行时需要随时访问,但不一定要持久化。
- 用户当前会话数据(已登录用户对象
UserModel) - 当前语言环境(如果不用持久化)
- 临时 Token(比如短期有效的 API Token)
- UI 运行时状态(比如 WebSocket 连接、推送监听器、是否第一次打开某个弹窗)
- App 运行时缓存(比如搜索结果、分页数据、滚动位置)
这些数据关掉 App 就可以丢掉,不需要跨会话保存。
适合放在 SharedPreferences 的数据
特点:需要跨会话保存(App 重启后仍然存在)。
- 用户登录状态(比如 Token、refreshToken、userId)
- 用户设置(主题模式、语言、字体大小、通知开关)
- 是否已完成新手引导/欢迎页(
isFirstOpen) - 本地缓存的业务配置(比如服务端下发的配置项)
- 最近一次打开的页面(某些 App 会恢复上次的浏览位置)
这些数据必须持久化,否则用户体验会受影响。
示例:主题模式保存与管理
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// 主题配置服务
class ThemeService extends GetxService {
late SharedPreferences _prefs;
final _isDark = false.obs; // 内存中的状态
bool get isDark => _isDark.value;
/// 初始化:加载 SharedPreferences
Future<ThemeService> init() async {
_prefs = await SharedPreferences.getInstance();
_isDark.value = _prefs.getBool("isDark") ?? false;
return this;
}
/// 切换主题
void toggleTheme() {
_isDark.value = !_isDark.value;
_prefs.setBool("isDark", _isDark.value); // 持久化保存
}
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// 把 ThemeService 注册成全局服务
await Get.putAsync(() => ThemeService().init());
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
final themeService = Get.find<ThemeService>();
return Obx(() => GetMaterialApp(
title: 'SharedPreferences + GetxService Demo',
theme: themeService.isDark ? ThemeData.dark() : ThemeData.light(),
home: const HomePage(),
));
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final themeService = Get.find<ThemeService>();
return Scaffold(
appBar: AppBar(title: const Text("GetxService + SharedPreferences")),
body: Center(
child: Obx(() => Text(
"当前主题:${themeService.isDark ? "Dark" : "Light"}",
style: const TextStyle(fontSize: 20),
)),
),
floatingActionButton: FloatingActionButton(
onPressed: () => themeService.toggleTheme(),
child: const Icon(Icons.brightness_6),
),
);
}
}
运行效果:
- 第一次运行时默认
Light。 - 点击按钮切换主题,会更新 UI,并存储到 SharedPreferences。
- 关闭应用重启,依然保持上次选择的主题(因为从 SharedPreferences 读取)。