Flutter:如何让前台服务感知应用的启停状态?
解决Flutter后台服务感知应用关闭状态的问题
针对你遇到的应用被清出最近任务时无法通过invoke通知后台服务的问题,这里提供几个可行的方案:
方案一:通过Android原生生命周期回调主动通知
当应用被从最近任务移除时,Flutter引擎已经和通道断开,没法再通过Flutter侧发消息,直接在Android原生的MainActivity里监听onTaskRemoved方法,直接通知后台服务更新状态:
class MainActivity : FlutterActivity() { override fun onTaskRemoved(rootIntent: Intent?) { super.onTaskRemoved(rootIntent) // 直接给后台服务发送应用关闭的状态 FlutterBackgroundService.getInstance().sendData( mapOf("appState" to "closed") ) } }
然后在Flutter后台服务的回调中接收这个数据,更新服务内部维护的应用状态标记即可。
方案二:后台服务主动检测应用进程存活状态
放弃依赖应用主动推送状态,改为后台服务定时主动检查主应用进程是否还在运行:
- 先在Android原生端实现一个检测进程的方法,通过MethodChannel暴露给Flutter:
class MainActivity : FlutterActivity() { override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, "app_process_check") .setMethodCallHandler { call, result -> if (call.method == "isAppRunning") { val activityManager = getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val runningProcesses = activityManager.runningAppProcesses val isRunning = runningProcesses.any { it.processName == packageName } result.success(isRunning) } } } }
- 在Flutter的后台服务中,每次执行定时任务前调用这个方法:
final methodChannel = MethodChannel('app_process_check'); // 服务的定时任务逻辑 Future<void> taskHandler() async { bool isAppRunning = false; try { isAppRunning = await methodChannel.invokeMethod('isAppRunning'); } catch (e) { // 调用失败默认认为应用已关闭 isAppRunning = false; } if (isAppRunning) { // 显示toast showToast(); } else { // 显示通知 showNotification(); } }
方案三:优化现有逻辑的容错与超时机制
如果想保留原有的状态推送逻辑,可以添加错误捕获+服务端超时判断:
- Flutter侧推送状态时捕获通道异常:
class _MyAppState extends State<MyApp> with WidgetsBindingObserver { final service = FlutterBackgroundService(); @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); try { service.invoke('updateAppState', {'state': state.name}); } catch (e) { // 通道关闭,说明应用已detached,这里可以记录本地状态,但更可靠的是服务端超时 } } }
- 在后台服务中维护一个
lastAppActiveTime变量,每次收到状态更新就刷新这个时间;执行定时任务时,如果当前时间和lastAppActiveTime的差值超过20秒(比你的10秒任务周期长就行),就认为应用已经关闭,切换到通知逻辑。
内容的提问来源于stack exchange,提问作者NCuth
相关产品推荐
相关产品推荐

