Flutter/Dart如何向Android端固定传递Long类型参数?
解决Dart向Android MethodChannel固定传递Long类型的问题
在Flutter/Dart与Android通过MethodChannel交互时,Dart的int会根据数值大小自动映射为Java的Integer(小数值,如100)或Long(大数值,如4284572001),导致Android端用call.argument<Long>("key1")接收小数值时抛出java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Long。以下是几种从Dart端固定发送Long类型的方案:
方案1:用BigInt包装数值
Dart中没有原生Long类型,但可以通过BigInt显式标记数值,让MethodChannel将其编码为Java端的Long(需确保数值在Long的范围:-2^63 到 2^63-1)。
Dart代码修改:
final int someNumber = 100; final Map<String, dynamic> myMap = {"key1": BigInt.from(someNumber)}; await channel.invokeMethod( channelMethodName, myMap, );
Android端接收代码调整:
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { val someNumber = call.argument<java.math.BigInteger>("key1")?.toLong() }
方案2:手动构造Long编码(基于StandardMessageCodec)
利用Flutter默认的StandardMessageCodec规则,Long类型的编码标记为0x04,可以通过ByteData手动构造Long数据:
import 'dart:typed_data'; final int someNumber = 100; final ByteData data = ByteData(8); data.setInt64(0, someNumber, Endian.host); final Map<String, dynamic> myMap = {"key1": data}; await channel.invokeMethod( channelMethodName, myMap, );
Android端读取ByteData转为Long:
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { val byteArray = call.argument<ByteArray>("key1") val someNumber = byteArray?.let { ByteBuffer.wrap(it).long } }
方案3:字符串传递(简单通用)
如果不想处理编码细节,可将数值转为字符串传递,两端再解析为Long:
Dart代码:
final int someNumber = 100; final Map<String, dynamic> myMap = {"key1": someNumber.toString()}; await channel.invokeMethod( channelMethodName, myMap, );
Android端解析:
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { val someNumber = call.argument<String>("key1")?.toLongOrNull() }
额外建议:Android端兼容处理
如果无需严格从Dart端固定类型,也可以在Android端直接兼容Integer和Long,接收Number类型再转为Long,这样无论Dart端发送什么数值类型都能正常处理:
override fun onMethodCall(call: MethodCall, result: MethodChannel.Result) { val someNumber = call.argument<Number>("key1")?.toLong() }
内容的提问来源于stack exchange,提问作者Nao Kreuzeder
相关产品推荐
相关产品推荐

