Flutter Method Channel传递自定义Pair类数组报错求解决方案
问题描述
通过Method Channel从Android宿主向Flutter客户端返回自定义Pair类数组时,出现以下错误:
Error retrieving id timestamp pairs: Unsupported value: 'com.example.my_app.Pair@f074fa2' of type 'class com.example.my_app.Pair'
Android端代码
自定义Pair类:
public class Pair { final String key; final Long value; Pair(String key, long value) { this.key = key; this.value = value; } }
主Activity中Method Channel配置:
@Override public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) { super.configureFlutterEngine(flutterEngine); new MethodChannel(flutterEngine.getDartExecutor().getBinaryMessenger(), CHANNEL) .setMethodCallHandler( (call, result) -> { // 运行在主线程 switch (call.method) { case "getPairs": List<Pair> pairs = getPairs(); result.success(pairs); break; default: result.notImplemented(); break; } }); }
Flutter端代码
Future<List<dynamic>> getIdTimestampsPairs() async { try { final List<dynamic> pairs = await _platform.invokeMethod('getIdTimestampPairs'); return pairs; } on PlatformException catch (e) { log('Error retrieving id timestamp pairs: ${e.message}'); return []; } }
已知可以拆分为两个方法分别返回key列表和value列表,询问是否有其他解决方案?
解决方案
Method Channel仅支持基础数据类型(字符串、数字、布尔等)及它们的集合(List、Map),自定义对象无法直接序列化传递。除拆分列表外,还有以下几种更优方案:
1. 将Pair转换为Map传递
这是最常用的方案,把每个Pair对象转为HashMap,再返回HashMap组成的列表:
case "getPairs": List<Pair> pairs = getPairs(); List<HashMap<String, Object>> resultList = new ArrayList<>(); for (Pair pair : pairs) { HashMap<String, Object> map = new HashMap<>(); map.put("key", pair.key); map.put("value", pair.value); resultList.add(map); } result.success(resultList); break;
Flutter端接收后,可直接处理Map,或转为自定义Dart类:
// 自定义Dart类 class IdTimestampPair { final String key; final int value; IdTimestampPair({required this.key, required this.value}); factory IdTimestampPair.fromMap(Map<String, dynamic> map) { return IdTimestampPair( key: map['key'] as String, value: map['value'] as int, ); } } // 修改后的获取方法(注意:Method调用名称要和Android端一致,此处统一为"getPairs") Future<List<IdTimestampPair>> getIdTimestampsPairs() async { try { final List<dynamic> rawPairs = await _platform.invokeMethod('getPairs'); return rawPairs.map((e) => IdTimestampPair.fromMap(e as Map<String, dynamic>)).toList(); } on PlatformException catch (e) { log('Error retrieving id timestamp pairs: ${e.message}'); return []; } }
2. 使用JSON序列化传递
将Pair列表序列化为JSON字符串,Flutter端再解析为对象:
Android端需引入JSON库(如Gson):
// 先添加Gson依赖,再实现序列化 case "getPairs": List<Pair> pairs = getPairs(); Gson gson = new Gson(); String jsonString = gson.toJson(pairs); result.success(jsonString); break;
Flutter端解析JSON:
Future<List<IdTimestampPair>> getIdTimestampsPairs() async { try { final String jsonString = await _platform.invokeMethod('getPairs'); final List<dynamic> jsonList = jsonDecode(jsonString); return jsonList.map((e) => IdTimestampPair.fromMap(e)).toList(); } on PlatformException catch (e) { log('Error retrieving id timestamp pairs: ${e.message}'); return []; } }
3. 实现Parcelable接口(适合复杂对象)
如果Pair类后续会扩展更多字段,可让其实现Android的Parcelable接口,传递Parcelable数组。但这种方式需要Flutter端做对应适配,实现成本较高,简单对象不推荐使用。
内容的提问来源于stack exchange,提问作者John Paul
相关产品推荐
相关产品推荐

