Flutter重启APP后点击退出登录无法跳转至登录页问题
问题分析
- 异步操作未等待:
deleteDatabase(path)是异步方法但未使用await,可能在数据库未删除完成时就执行后续操作,引发状态不一致。 - 导航与Phoenix重启冲突:手动调用
Navigator.pushAndRemoveUntil后立即执行Phoenix.rebirth,两者同时修改页面栈/应用状态,导致导航逻辑被覆盖,重启后初始路由未正确更新。 - LocationService实例不统一:退出时调用
LocationService().dispose()创建了新实例,而非main中启动的那个,导致监听未正确释放,可能引发资源泄漏和应用冻结。
修复方案
1. 修正退出登录方法,确保异步操作完成并调整逻辑
将所有异步操作等待完成,移除手动导航,依赖Phoenix重启后自动读取SharedPreferences状态跳转登录页:
signOut(BuildContext context) async { // 保存未登录状态 await SharedPref.saveLoginSharedPreference(false); // 等待数据库删除完成 var databasesPath = await getDatabasesPath(); String path = join(databasesPath, 'patient.db'); await deleteDatabase(path); // 释放单例LocationService资源 await LocationService.instance.dispose(); // 重启应用,由main重新读取状态决定初始路由 Phoenix.rebirth(context); }
2. 将LocationService改为单例模式
确保整个应用使用同一个实例,避免资源泄漏:
class LocationService { static final LocationService _instance = LocationService._internal(); factory LocationService() => _instance; LocationService._internal(); // 原有方法保留,修改dispose逻辑确保释放资源 void dispose() { getListener()?.dispose(); } }
同时修改main中的调用:
LocationService.instance.getListener()?.resume();
3. 清理MaterialApp路由配置冲突
移除home属性,仅保留initialRoute避免路由逻辑冲突:
@override Widget build(BuildContext context) { return MaterialApp( title: 'My Main', debugShowCheckedModeBanner: false, theme: ThemeData( primarySwatch: Colors.blue, primaryColor: Colors.blue[100], ), initialRoute: homepage, routes: { '/questionnairePushNotificationRoot': (context) => const QuestionnaireRoot(), '/singleChoiceNew': (context) => const SelectionWindow(), '/exercisePrescriptionPage': (context) => const ExercisePrescriptionHome(), '/multipleChoice': (context) => const MultipleChoice(), '/scale': (context) => const Scale(), '/textfield': (context) => const FreeTextfield(), '/endScreen': (context) => const EndScreen(), '/loginScreen': (context) => const LoginScreen(), '/registerScreen': (context) => const RegisterScreen(), '/forgotPassword': (context) => const ForgotPassword(), '/training': (context) => const Training(), '/riskFactors': (context) => const RiskFactors(), '/chat': (context) => const ChatDetailPage(), }, ); }
关键修复说明
- 等待所有异步操作完成后再重启应用,避免状态不一致。
- 用单例管理LocationService,确保资源正确释放,解决冻结问题。
- 依赖Phoenix重启后重新读取SharedPreferences状态,避免手动导航与重启的冲突。
内容的提问来源于stack exchange,提问作者Iman
相关产品推荐
相关产品推荐

