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

多次调用result.success致Flutter与Android交互崩溃问题求助

问题原因

你遇到的崩溃是因为MethodChannel的Result对象是单次请求-响应绑定的:每个invokeMethod调用对应一个唯一的Result,第一次调用result.success后,这个Result就会被标记为已完成,后续重复调用会触发Flutter端的断言错误,直接导致崩溃。你的场景需要多次推送回调数据,而MethodChannel是「单次请求-响应」模型,完全不匹配。

解决方案:改用EventChannel实现持续事件推送

EventChannel专门用于原生向Flutter推送持续的事件流,完美适配多次回调的场景,具体实现如下:

Android 原生侧实现

1. 注册EventChannel

在你的Flutter容器(Activity/Fragment)中初始化并注册EventChannel:

import io.flutter.plugin.common.EventChannel;
import io.flutter.embedding.android.FlutterActivity;

public class MainActivity extends FlutterActivity {
    private static final String EVENT_CHANNEL_NAME = "com.your.app/ui_events";
    private MyEventsListener eventsListener;

    @Override
    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
        super.configureFlutterEngine(flutterEngine);
        
        // 注册EventChannel处理事件流
        new EventChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), EVENT_CHANNEL_NAME)
                .setStreamHandler(new EventChannel.StreamHandler() {
                    @Override
                    public void onListen(Object arguments, EventChannel.EventSink events) {
                        // Flutter侧开始监听时,注册原生事件回调
                        eventsListener = new MyEventsListener() {
                            @Override
                            public void onEventDone(MyEvent myEvent) {
                                if (myEvent != null) {
                                    JSONObject jsonObject = new JSONObject();
                                    try {
                                        jsonObject.put("event_id", myEvent.eventID());
                                        jsonObject.put("event_name", myEvent.eventName());
                                        jsonObject.put("event_type", myEvent.eventType());
                                        jsonObject.put("event_label", myEvent.eventLabel());
                                    } catch (JSONException e) {
                                        e.printStackTrace();
                                        events.error("JSON_PARSE_ERROR", "Failed to parse event data", null);
                                        return;
                                    }
                                    // 可多次调用events.success推送数据
                                    events.success(jsonObject.toString());
                                } else {
                                    events.error("NULL_EVENT", "Could not fetch event data", null);
                                }
                            }
                        };
                        EVENT.trackUIEvents(eventsListener);
                    }

                    @Override
                    public void onCancel(Object arguments) {
                        // Flutter侧取消监听时,移除原生回调避免内存泄漏
                        if (eventsListener != null) {
                            // 请确保EVENT类提供移除监听的方法,比如:
                            // EVENT.removeUIEventsListener(eventsListener);
                            eventsListener = null;
                        }
                    }
                });
    }
}

Flutter 侧实现

1. 创建事件监听服务

import 'dart:convert';
import 'package:flutter/services.dart';

class UIEventsTracker {
  static const EventChannel _eventChannel = EventChannel('com.your.app/ui_events');
  StreamSubscription? _subscription;

  // 返回事件流,供页面监听
  Stream<Map<String, dynamic>> getEventStream() {
    return _eventChannel.receiveBroadcastStream().map((event) {
      final jsonString = event as String;
      return json.decode(jsonString) as Map<String, dynamic>;
    });
  }

  // 停止监听(页面销毁时调用)
  void stopTracking() {
    _subscription?.cancel();
    _subscription = null;
  }
}

2. 在页面中使用监听

import 'package:flutter/material.dart';

class EventPage extends StatefulWidget {
  const EventPage({super.key});

  @override
  State<EventPage> createState() => _EventPageState();
}

class _EventPageState extends State<EventPage> {
  final UIEventsTracker _tracker = UIEventsTracker();

  @override
  void initState() {
    super.initState();
    // 开始监听事件
    _tracker.getEventStream().listen((event) {
      // 每次收到原生推送的事件,都会触发这里
      print('Received UI Event: $event');
      // 处理事件数据、更新UI等操作
    }, onError: (error) {
      print('Event Error: $error');
    });
  }

  @override
  void dispose() {
    // 页面销毁时停止监听,避免内存泄漏
    _tracker.stopTracking();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('UI Events Tracker')),
      body: const Center(child: Text('Listening for UI events...')),
    );
  }
}
备选方案:保留MethodChannel(仅适合单次拉取)

如果你的场景不需要实时推送,只是每次主动拉取最新事件,可以修改MethodChannel实现,确保每个Result只被调用一次:

case MY_EVENTS:
    // 每次调用方法时创建独立的监听
    MyEventsListener singleUseListener = new MyEventsListener() {
        @Override
        public void onEventDone(MyEvent myEvent) {
            // 回调后立即移除监听,避免重复触发
            EVENT.removeUIEventsListener(this);
            if (myEvent != null) {
                JSONObject jsonObject = new JSONObject();
                try {
                    jsonObject.put("event_id", myEvent.eventID());
                    jsonObject.put("event_name", myEvent.eventName());
                    jsonObject.put("event_type", myEvent.eventType());
                    jsonObject.put("event_label", myEvent.eventLabel());
                } catch (JSONException e) {
                    e.printStackTrace();
                    result.error("0", "Parse failed", null);
                    return;
                }
                result.success(jsonObject.toString());
            } else {
                result.error("0", "No data", null);
            }
        }
    };
    EVENT.trackUIEvents(singleUseListener);
    break;

这种方式下,Flutter侧每次调用trackUIEvents()只会获取一次最新事件,无法接收主动推送的更新。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 21:57:40