Flutter熄屏时setState()执行问题及屏幕亮灭状态检测方法
Flutter 熄屏场景下setState执行异常解决方案
针对音频类应用适配熄屏场景的两个诉求,分别给出可直接落地的实现方式:
方案一:检测屏幕亮灭状态,仅亮屏时触发UI刷新
这是最符合熄屏省电需求的方案,不会产生无意义的性能和电量损耗:
- 跨端状态同步:安卓端监听系统
ACTION_SCREEN_ON、ACTION_SCREEN_OFF系统广播,iOS端监听UIScreen.brightnessDidChangeNotification结合屏幕锁定状态判断亮灭,通过MethodChannel将屏幕状态实时同步到Flutter层,用全局变量维护即可。 - 业务逻辑调整:音频播放进度的计算、存储逻辑不要和UI刷新绑定,熄屏状态下依然正常更新内存中的播放进度、播放状态等数据,仅在判断屏幕点亮时才调用
setState()刷新界面,核心逻辑示例:
// 全局维护的状态 bool isScreenOn = true; Duration currentPlayPosition = Duration.zero; // 播放进度回调逻辑 void handleProgressUpdate(Duration newPosition) { // 无论亮屏熄屏,始终更新最新的进度值 currentPlayPosition = newPosition; // 仅亮屏时触发UI重绘 if (isScreenOn) { setState(() {}); } }
补充处理:屏幕从熄灭切换到点亮的瞬间,主动触发一次
setState(),避免界面显示的进度停留在熄屏前的旧值。
方案二:配置系统权限,保证熄屏时setState正常执行
该方案会额外增加电量消耗,不符合熄屏省电的设计目标,非必要不选用:
- 安卓端配置:
- 在清单文件中添加权限声明:
<uses-permission android:name="android.permission.WAKE_LOCK" /> - 音频前台服务启动时,持有
PARTIAL_WAKE_LOCK保证CPU不会因熄屏进入休眠 - 重写MainActivity的Flutter引擎绑定逻辑,关闭引擎在界面不可见时自动暂停帧调度的默认策略,此时
setState()标记的UI更新任务不会被系统挂起,会正常执行。
- 在清单文件中添加权限声明:
- iOS端配置:开启音频后台播放模式后,系统不会暂停应用的UI线程调度,
setState()可以正常执行,但由于屏幕处于熄灭状态,所有UI绘制操作不会产生实际显示效果,只会空耗性能。
内容的提问来源于stack exchange,提问作者andyandy
相关产品推荐
相关产品推荐

