Flutter Getx中Controller的onInit未调用致闪屏卡住,Middleware报错如何解决?
问题原因与解决方案
1. MainPageController的onInit未被调用
- 根因:你使用
Get.lazyPut注册MainPageController,懒加载机制要求Controller被首次主动访问时才会实例化并执行onInit。你的SplashScreen虽然继承了GetView<MainPageController>,但整个build方法里没有任何访问controller实例的逻辑,GetX不会主动初始化未被使用的懒加载实例,因此onInit不会执行。 - 解决方案:任选其一即可
- 在SplashScreen的build方法中增加对controller的访问,例如首行加
controller;触发实例化 - 将Bind类中MainPageController的注册方式从
Get.lazyPut改为Get.put,绑定时直接初始化实例 - 在SplashScreen的initState生命周期中主动调用
Get.find<MainPageController>()触发实例化
- 在SplashScreen的build方法中增加对controller的访问,例如首行加
2. 中间件报错找不到LoginPageController
- 根因:两个逻辑顺序问题叠加导致
- GetPage的中间件
redirect方法执行时机早于当前页面的Binding依赖注入,你将Bind类绑定在splashScreen页面上,中间件执行时Bind的dependencies方法还未执行,LoginPageController还没被注册到Get容器中 - 你将
Get.find<LoginPageController>写在GlobalMiddleware的类成员变量初始化位置,该代码会在GlobalMiddleware实例化时立即执行,比redirect方法的执行时机更早,此时根本没有完成依赖注册
- GetPage的中间件
- 解决方案:
- 第一步:调整全局依赖初始化时机,在应用启动时就注册全局需要的Controller,不要绑定在单独页面的Binding中。修改main函数代码:
void main() { WidgetsFlutterBinding.ensureInitialized(); // 提前初始化全局依赖 Bind().dependencies(); runApp(const MyApp()); }
- 第二步:修改GlobalMiddleware代码,将Get.find逻辑移到redirect方法内部:
class GlobalMiddleware extends GetMiddleware { @override RouteSettings? redirect(String? route) { // 移到方法内获取,确保依赖已注册完成 final authService = Get.find<LoginPageController>(); print(authService.isLogin.value); return authService.isLogin.value == true ? const RouteSettings(name: "/mainPage") : const RouteSettings(name: "/login"); } }
- 补充:如果不需要保留闪屏展示时长,该方案可以正常工作;如果需要闪屏展示固定时长/资源加载完成后再跳转,不建议用中间件处理闪屏跳转逻辑,直接在SplashScreen的initState中执行判断跳转逻辑即可。
内容的提问来源于stack exchange,提问作者Hoo
相关产品推荐
相关产品推荐

