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

如何通过Method Channel从Flutter向Android Java传递对象/列表数据?

Flutter与Android通过Method Channel/Event Channel传递对象、列表数据实现方案

一、传递单个对象数据

Flutter端实现

假设你从数据库获取到的对象是DeviceData实例,先将其转为Map<String, dynamic>(Method Channel仅支持基础类型、Map、List这类可序列化数据),再通过Method Channel传递:

// 数据库对象模型
class DeviceData {
  final double bVolt;
  final double hstring;
  final double qString;
  final double externalDeg;
  final double extDeg;
  final int sessionNo;

  DeviceData({
    required this.bVolt,
    required this.hstring,
    required this.qString,
    required this.externalDeg,
    required this.extDeg,
    required this.sessionNo,
  });

  // 转为可跨平台传递的Map
  Map<String, dynamic> toMap() {
    return {
      'bVolt': bVolt,
      'hstring': hstring,
      'qString': qString,
      'externalDeg': externalDeg,
      'extDeg': extDeg,
      'sessionNo': sessionNo,
    };
  }
}

// 发送对象的方法
void sendDeviceData(DeviceData data) async {
  final session = StateInheritedWidget.of(context).state.session;
  String responseMsg;
  try {
    final String result = await sendData.invokeMethod(
      'sendDeviceData',
      data.toMap(), // 传递转换后的Map
    );
    responseMsg = '发送对象成功,响应:$result';
  } on PlatformException catch (e) {
    responseMsg = '发送失败:${e.message}';
  }
}

Android Java端实现

在Method Channel回调中,获取传递的Map并解析为Java实体类:

// 定义对应Java实体类
public class DeviceData {
    private double bVolt;
    private double hstring;
    private double qString;
    private double externalDeg;
    private double extDeg;
    private int sessionNo;

    // 从Map解析构造对象
    public DeviceData(Map<String, Object> map) {
        this.bVolt = (double) map.get("bVolt");
        this.hstring = (double) map.get("hstring");
        this.qString = (double) map.get("qString");
        this.externalDeg = (double) map.get("externalDeg");
        this.extDeg = (double) map.get("extDeg");
        // 兼容Flutter int转Java的Number类型
        this.sessionNo = ((Number) map.get("sessionNo")).intValue();
    }

    // 按需添加getter方法
    public double getbVolt() { return bVolt; }
    public int getSessionNo() { return sessionNo; }
}

// Method Channel处理逻辑
new MethodChannel(getFlutterView(), "your_channel_name").setMethodCallHandler(
    (call, result) -> {
        if (call.method.equals("sendDeviceData")) {
            // 获取Flutter传递的Map数据
            Map<String, Object> dataMap = (Map<String, Object>) call.arguments;
            DeviceData deviceData = new DeviceData(dataMap);
            
            // 业务逻辑处理示例
            double volt = deviceData.getbVolt();
            int session = deviceData.getSessionNo();
            
            // 返回响应给Flutter
            result.success("已接收对象数据");
        } else {
            result.notImplemented();
        }
    }
);

二、通过Method Channel传递数据列表

Flutter端实现

将列表中的每个对象转为Map,再传递List<Map>集合:

// 发送数据列表的方法
void sendDeviceDataList(List<DeviceData> dataList) async {
  String responseMsg;
  try {
    // 将每个对象转为Map,组成列表
    List<Map<String, dynamic>> mapList = dataList.map((data) => data.toMap()).toList();
    final String result = await sendData.invokeMethod(
      'sendDeviceDataList',
      mapList,
    );
    responseMsg = '发送列表成功,响应:$result';
  } on PlatformException catch (e) {
    responseMsg = '发送列表失败:${e.message}';
  }
}

Android Java端实现

获取List后,循环解析每个Map为Java实体:

// Method Channel列表处理逻辑
new MethodChannel(getFlutterView(), "your_channel_name").setMethodCallHandler(
    (call, result) -> {
        if (call.method.equals("sendDeviceDataList")) {
            // 获取Flutter传递的列表数据
            List<Map<String, Object>> dataList = (List<Map<String, Object>>) call.arguments;
            List<DeviceData> deviceDataList = new ArrayList<>();
            
            // 循环解析每个Map为实体类
            for (Map<String, Object> map : dataList) {
                deviceDataList.add(new DeviceData(map));
            }
            
            // 业务逻辑示例:遍历列表打印数据
            for (DeviceData data : deviceDataList) {
                Log.d("DeviceData", "电压:" + data.getbVolt());
            }
            
            result.success("已接收列表,共" + deviceDataList.size() + "条数据");
        } else {
            result.notImplemented();
        }
    }
);

三、通过Event Channel传递数据列表(流式推送)

如果需要持续推送实时更新的列表数据(比如数据库变化同步),使用Event Channel更合适:

Flutter端实现

创建Stream监听数据源,通过Event Channel发送流式数据:

// 初始化Event Channel
final EventChannel _eventChannel = EventChannel("your_event_channel_name");

// 配置数据流推送
void setupEventStream() {
  // 假设从数据库获取实时数据流(如sqflite/Room的监听流)
  Stream<List<DeviceData>> dbStream = yourDatabase.getDeviceDataStream();
  
  _eventChannel.setStreamHandler(
    StreamHandler(
      onListen: (arguments, events) {
        // 订阅数据库流,实时推送数据到Android
        dbStream.listen(
          (dataList) {
            List<Map<String, dynamic>> mapList = dataList.map((d) => d.toMap()).toList();
            events.success(mapList);
          },
          onError: (error) {
            events.error("STREAM_ERROR", error.toString(), null);
          },
        );
      },
      onCancel: (arguments) {
        // 取消订阅逻辑(如关闭数据库监听)
      },
    ),
  );
}

Android Java端实现

注册Event Channel监听器,接收流式列表数据:

// 初始化并监听Event Channel
new EventChannel(getFlutterView(), "your_event_channel_name").setStreamHandler(
    new EventChannel.StreamHandler() {
        @Override
        public void onListen(Object arguments, EventChannel.EventSink events) {
            events.setEventListener(new EventChannel.EventListener() {
                @Override
                public void onEvent(Object event) {
                    if (event instanceof List) {
                        List<Map<String, Object>> dataList = (List<Map<String, Object>>) event;
                        List<DeviceData> deviceDataList = new ArrayList<>();
                        
                        for (Map<String, Object> map : dataList) {
                            deviceDataList.add(new DeviceData(map));
                        }
                        
                        // 处理实时收到的列表数据
                        Log.d("EventChannel", "收到新数据列表,共" + deviceDataList.size() + "条");
                    }
                }

                @Override
                public void onError(Object error) {
                    Log.e("EventChannel", "数据流错误:" + error.toString());
                }
            });
        }

        @Override
        public void onCancel(Object arguments) {
            // 取消监听后的清理逻辑
        }
    }
);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 13:35:31