Flutter中如何检测应用从最近应用列表中被移除?
解决Flutter应用从最近列表移除的检测问题
当你从最近应用列表移除Flutter应用时,AppLifecycleState.detached往往不会被触发——这是因为系统此时会直接终止应用进程,Flutter的生命周期回调没有机会执行。下面分平台给出可行的解决方案:
Android平台:监听onTaskRemoved
Android在应用从最近列表被移除时,会触发Activity的onTaskRemoved方法,我们可以通过MethodChannel将这个事件传递给Flutter:
Flutter端代码修改
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class MyApp extends StatefulWidget { @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> with WidgetsBindingObserver { late MethodChannel _channel; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); // 初始化MethodChannel _channel = MethodChannel('app_lifecycle_channel'); _channel.setMethodCallHandler((call) async { if (call.method == 'onTaskRemoved') { // 这里处理应用从最近列表被移除的逻辑 print('应用已从最近列表移除'); } }); } @override void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } @override void didChangeAppLifecycleState(AppLifecycleState state) { super.didChangeAppLifecycleState(state); // 保留原有生命周期逻辑 } @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( appBar: AppBar(title: const Text('My App')), body: const Center(child: Text('Hello, World!')), ), ); } }
Android原生代码修改
打开android/app/src/main/kotlin/[你的包名]/MainActivity.kt,重写onTaskRemoved方法:
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.engine.FlutterEngine import io.flutter.plugin.common.MethodChannel class MainActivity : FlutterActivity() { private val CHANNEL = "app_lifecycle_channel" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> // 处理Flutter端调用(如果需要) } } override fun onTaskRemoved(rootIntent: android.content.Intent?) { super.onTaskRemoved(rootIntent) // 通过MethodChannel通知Flutter MethodChannel(flutterEngine?.dartExecutor?.binaryMessenger, CHANNEL).invokeMethod("onTaskRemoved", null) } }
iOS平台:监听applicationWillTerminate
iOS在应用被终止时会调用applicationWillTerminate方法(注意:如果应用处于后台挂起状态,系统可能直接终止进程而不触发此方法,但从最近列表移除后若进程被立刻终止,该方法会执行):
Flutter端代码修改
和Android端类似,使用MethodChannel监听:
// 同Android端的Flutter代码,修改MethodChannel回调逻辑 _channel.setMethodCallHandler((call) async { if (call.method == 'onAppTerminated') { print('应用已从最近列表移除并终止'); } });
iOS原生代码修改
打开ios/Runner/AppDelegate.swift,修改如下:
import UIKit import Flutter @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { private let CHANNEL = "app_lifecycle_channel" override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.setMethodCallHandler({ [weak self] (call: FlutterMethodCall, result: FlutterResult) -> Void in // 处理Flutter调用 }) GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func applicationWillTerminate(_ application: UIApplication) { super.applicationWillTerminate(application) let controller : FlutterViewController = window?.rootViewController as! FlutterViewController let channel = FlutterMethodChannel(name: CHANNEL, binaryMessenger: controller.binaryMessenger) channel.invokeMethod("onAppTerminated", arguments: nil) } }
注意事项
- Android的
onTaskRemoved会在应用从最近列表被移除时准确触发,不管应用是否在前台。 - iOS的
applicationWillTerminate不一定能100%捕获所有从最近列表移除的场景,因为iOS可能会将应用挂起而不立刻终止,但对于进程被直接杀死的情况,该方法会执行。 - 所有在这些回调中执行的逻辑要尽量轻量化,因为进程即将终止,耗时操作可能无法完成。
内容的提问来源于stack exchange,提问作者Gowtham
相关产品推荐
相关产品推荐

