Flutter接入Firebase后报错window属性无法无条件访问 接收者可为null
问题原因
该报错和接入Firebase没有直接关系。触发原因是Flutter 3.0及以上版本启用健全空安全后,WidgetsBinding.instance的类型从非空的WidgetsBinding调整为可空的WidgetsBinding?,直接无条件访问它的window属性就会抛出这个编译错误。接入Firebase时一般会同步升级项目依赖、适配高版本SDK,刚好触发了这次API变更带来的问题。
修复方法
直接替换原有尺寸适配代码为如下版本即可,既处理了空安全校验问题,也适配了高版本Flutter中已经废弃的旧API:
// 提前完成binding初始化,保证后续访问不存在空风险 final binding = WidgetsFlutterBinding.ensureInitialized(); Size size = binding.window.physicalSize / binding.window.devicePixelRatio; /// 根据视口宽度设置屏幕、组件的左右内/外边距与宽度 double getHorizontalSize(double px) { return px * (size.width / 360); } /// 根据视口高度设置屏幕、组件的上下内/外边距与高度 double getVerticalSize(double px) { // 旧版fromWindow方法已废弃,替换为fromView适配高版本SDK num statusBar = MediaQueryData.fromView(binding.window).viewPadding.top; num screenHeight = size.height - statusBar; return px * (screenHeight / 800); } /// 根据视口尺寸自适应文本字号 double getFontSize(double px) { final height = getVerticalSize(px); final width = getHorizontalSize(px); return height < width ? height.toInt().toDouble() : width.toInt().toDouble(); } /// 计算图片宽高适配后的最小像素值 double getSize(double px) { final height = getVerticalSize(px); final width = getHorizontalSize(px); return height < width ? height.toInt().toDouble() : width.toInt().toDouble(); }
如果暂时不想调整原有代码逻辑,只想快速解决编译报错,也可以在所有WidgetsBinding.instance后追加空断言!,强制声明该对象非空,比如写成WidgetsBinding.instance!.window。但要注意必须保证在调用这些尺寸方法之前,已经执行过WidgetsFlutterBinding.ensureInitialized()完成初始化,否则会触发运行时空指针错误。
补充:如果你的项目使用Flutter 3.10及以上版本,更推荐用
View.of(context)或PlatformDispatcher.instance.implicitView获取窗口信息,以更好适配多窗口、多视图场景,上面的修复方案可以满足绝大多数单窗口应用的使用需求。
内容的提问来源于stack exchange,提问作者John Michael Tan
相关产品推荐
相关产品推荐

