You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 06:46:20