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

Flutter main.dart出现LateInitializationError及SharedPreferences双登录处理问题

LateInitializationError 报错修复

报错原因

你声明的late bool userLoggedIn为延迟初始化变量,getLoggedInState属于异步方法,initState调用该方法后不会等待异步逻辑执行完成,就会触发首次build渲染,此时userLoggedIn还未完成赋值,就会触发延迟初始化报错。
你所说的bool? userLoggedIn写法不被Flutter允许,本质是你未处理可空变量的空值判断逻辑,直接将可空变量用于页面路由判断导致的编译错误。

修复后的完整代码

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await Firebase.initializeApp();
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  // 改为可空类型,空值代表还未读取到登录状态
  bool? userLoggedIn;
  @override
  void initState() {
    getLoggedInState();
    super.initState();
  }

  getLoggedInState() async {
    final value = await HelperFunctions.getUserLoggedInSharedPreference();
    setState(() {
      // 处理空值默认逻辑,未读取到状态时默认视为未登录
      userLoggedIn = value ?? false;
    });
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Dashee',
        theme: ThemeData(
          primarySwatch: Colors.deepPurple,
        ),
        // 先判断是否读取到状态,未读取到时优先显示启动页
        home: userLoggedIn == null 
          ? const Splash() 
          : (userLoggedIn! ? const Dashboard() : const Login()));
  }
}

注意:如果原来的未登录跳转页不是Login可以自行替换为你项目中的对应页面


SharedPreferences 处理双登录场景方案

双登录场景(比如普通用户/商家、个人账号/企业账号两类身份登录)的处理逻辑如下:

  • 存储登录信息时,除了存储是否登录的布尔值,额外新增登录身份类型字段,比如用整数标识:0代表普通用户,1代表商家
  • 读取登录状态时,同步读取登录身份字段,根据两个字段的结果判断跳转对应身份的首页
  • 退出登录时,需要同时清空登录状态、登录身份两个字段,避免数据残留导致逻辑错误

工具类示例代码

class HelperFunctions {
  static String userLoggedInKey = "USERLOGGEDINKEY";
  static String loginTypeKey = "LOGINTYPEKEY"; // 0=普通用户 1=商家

  // 保存登录信息
  static Future<void> saveLoginInfo(bool isLoggedIn, int type) async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    await sp.setBool(userLoggedInKey, isLoggedIn);
    await sp.setInt(loginTypeKey, type);
  }

  // 读取登录状态
  static Future<bool?> getUserLoggedInSharedPreference() async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    return sp.getBool(userLoggedInKey);
  }

  // 读取登录身份
  static Future<int?> getLoginType() async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    return sp.getInt(loginTypeKey);
  }

  // 清空登录信息(退出登录时调用)
  static Future<void> clearLoginInfo() async {
    SharedPreferences sp = await SharedPreferences.getInstance();
    await sp.remove(userLoggedInKey);
    await sp.remove(loginTypeKey);
  }
}

调整路由判断逻辑

修改getLoggedInState方法和路由判断即可:

class _MyAppState extends State<MyApp> {
  bool? userLoggedIn;
  int? loginType;

  getLoggedInState() async {
    final loggedIn = await HelperFunctions.getUserLoggedInSharedPreference();
    final type = await HelperFunctions.getLoginType();
    setState(() {
      userLoggedIn = loggedIn ?? false;
      loginType = type;
    });
  }

  @override
  Widget build(BuildContext context) {
    SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'Dashee',
        theme: ThemeData(
          primarySwatch: Colors.deepPurple,
        ),
        home: userLoggedIn == null 
          ? const Splash() 
          : !userLoggedIn! 
            ? const Login()
            : (loginType == 0 ? const UserDashboard() : const MerchantDashboard()));
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:36:03