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

Flutter应用后台/关闭时调用Android原生代码实现会话通知快捷方式问题

问题根本原因

  1. 最初将MethodChannel注册在MainActivity中,应用退后台/被杀后Activity销毁,对应的通道实例也随之销毁,自然无法响应调用。
  2. 你后续在Service中新建独立FlutterEngine注册通道的方案会出现MissingPluginException,是因为Dart侧后台触发调用的isolate和Service中新建的FlutterEngine不属于同一个上下文,通道注册完全错位,同时你报错提到的saveBitmapAsCircle方法对应的通道没有在这个新的FlutterEngine中注册,自然找不到实现。

推荐解决方案(无需处理Flutter生命周期兼容,适配全场景)

你当前的核心诉求是收到推送后生成会话快捷方式并展示通知,完全可以绕过Dart调用原生的链路,直接在原生侧处理全部逻辑:

  1. 原生侧实现FirebaseMessagingService子类,接管推送接收逻辑:
class MyFirebaseMessagingService : FirebaseMessagingService() {
    private val CHANNEL = "..."
    // 复用你之前的创建快捷方式逻辑
    private fun createConversationShortcut(personName: String, personIcon: String): String {
        val person = Person.Builder()
                .setName(personName)
                .setIcon(IconCompat.createWithContentUri(personIcon))
                .build()
        val shortcutId = personName.lowercase(Locale.ROOT).replace(" ", "_") + "_shortcut"
        val shortcut = ShortcutInfoCompat.Builder(this, shortcutId)
                .setLongLived()
                .setIntent(Intent(Intent.ACTION_VIEW))
                .setPerson(person)
                .setShortLabel(personName)
                .build()
        ShortcutManagerCompat.addDynamicShortcuts(this, listOf(shortcut))
        return shortcutId
    }

    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        super.onMessageReceived(remoteMessage)
        // 解析推送参数里的personName、personIcon、通知内容等字段
        val personName = remoteMessage.data["personName"] ?: return
        val personIcon = remoteMessage.data["personIcon"] ?: return
        val notificationTitle = remoteMessage.data["title"] ?: return
        val notificationContent = remoteMessage.data["content"] ?: return
        // 生成shortcutId
        val shortcutId = createConversationShortcut(personName, personIcon)
        // 直接在原生侧构建带shortcutId的通知展示即可,无需传回Dart侧
        // 其他通知配置和MessagingStyle配置也可以直接在原生侧写,调用NotificationManager展示通知即可
    }
}
  1. 不要忘记在AndroidManifest.xml中注册这个服务:
<service
    android:name=".MyFirebaseMessagingService"
    android:exported="false">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
</service>

该方案完全不依赖FlutterEngine的存活状态,应用退后台、被杀场景都可以正常运行。


备选方案:必须从Dart侧调用原生的处理方式

如果你的业务逻辑必须在Dart侧处理,再调用原生创建快捷方式,可以通过全局FlutterEngine实现:

  1. 自定义Application类,初始化全局共用的FlutterEngine,统一注册所有MethodChannel:
class MyApp : Application() {
    lateinit var globalFlutterEngine: FlutterEngine
    private val CHANNEL = "..."

    override fun onCreate() {
        super.onCreate()
        // 初始化全局FlutterEngine
        globalFlutterEngine = FlutterEngine(this)
        globalFlutterEngine.dartExecutor.executeDartEntrypoint(
            DartExecutor.DartEntrypoint.createDefault()
        )
        // 统一注册所有需要的MethodChannel,包括createConversationShortcut和saveBitmapAsCircle
        MethodChannel(globalFlutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
            when(call.method) {
                "createConversationShortcut" -> {
                    val personName = call.argument<String>("personName")
                    val personIcon = call.argument<String>("personIcon")
                    if (personName != null && personIcon != null) {
                        val shortcutId = createConversationShortcut(personName, personIcon)
                        result.success(shortcutId)
                    } else {
                        result.error("argument-error", "Too few arguments", null)
                    }
                }
                "saveBitmapAsCircle" -> {
                    // 在这里实现对应的逻辑,不要只在MainActivity中注册
                }
                else -> result.notImplemented()
            }
        }
    }

    private fun createConversationShortcut(personName: String, personIcon: String): String {
        // 复用之前的创建快捷方式逻辑
    }
}
  1. 在MainActivity中复用这个全局FlutterEngine,不要重复创建:
class MainActivity: FlutterActivity() {
    override fun provideFlutterEngine(context: Context): FlutterEngine {
        return (application as MyApp).globalFlutterEngine
    }
}
  1. 不需要再单独在Service中注册通道,所有调用都会走全局FlutterEngine的通道,不会再出现找不到实现的问题。

内容的提问来源于stack exchange,提问作者arzi89

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 15:15:02