原生与Flutter通信
Posted Ever69
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原生与Flutter通信相关的知识,希望对你有一定的参考价值。
之前讲过一篇Flutter与原生通信,为大家讲解了Flutter如何调用原生,但是没有介绍原生如何调用Flutter,那么原生如何调用Flutter呢?
诶~,还是通过MethodChannel,只不过这次它俩角色互换了一下,之前是原生作为通信方法的提供方,Flutter为调用方,现在倒过来了,Flutter作为通信方法的提供方,原生作为调用方。是不是很有意思。
Flutter端(提供方)
和在原生中一样,通过MethodChannel的setMethodCallHandler方法进行注册,提供原生调用的通信方法。需要实现一个参数为MethodCall,返回值为Future对象的函数。
void setMethodCallHandler(Future<dynamic> Function(MethodCall call)? handler)
_methodChannelHandlers[this] = handler;
binaryMessenger.setMessageHandler(
name,
handler == null
? null
: (ByteData? message) => _handleAsMethodCall(message, handler),
);
MethodCall
MethodCall应该不陌生吧,在上一篇博客了我们见过它了,但是Flutter中的MethodCall和原生中的MethodCall还有点不一样,Flutter中的MethodCall只有属性,没有方法。
/// 表示调用命名方法的命令对象。
@immutable
class MethodCall
/// 创建一个 [MethodCall],表示使用指定的 [arguments] 调用 [method]。
const MethodCall(this.method, [this.arguments])
: assert(method != null);
/// 要调用的方法的名称。
final String method;
/// 方法的参数。
///
/// 必须是使用的 [MethodCodec] 的有效值。
///
/// 这个属性是动态的,这意味着访问时会跳过类型检查
/// 这个性质。 为了最大限度地降低运行时类型错误的风险,该值应该访问时被强制转换为`Object?`。
final dynamic arguments;
@override
String toString() => '$objectRuntimeType(this, 'MethodCall')($method, $arguments)';
我们在flutter中注册一个’lal‘方法,将原生传递过来的参数编成一段话返回给原生。
static const nativeChannel =
const MethodChannel("com.fengwo.reading.flutter_app/native");
//对方法进行注册
nativeChannel.setMethodCallHandler((call)
if(call.method == "lal")
return Future.value("Hello~ $call.arguments\\nI'm flutter");
return null;
);
原生端(调用方)
原生中调用flutter,同样通过MethodChannel的invokeMethod方法,其有三个参数,第一个是flutter中定义的方法名称,第二个是要传递的参数,第三个是调用flutter方法结果的回调接口。
@UiThread
public void invokeMethod(String method, @Nullable Object arguments, @Nullable Result callback)
messenger.send(
name,
codec.encodeMethodCall(new MethodCall(method, arguments)),
callback == null ? null : new IncomingResultHandler(callback));
现在,我们使用原生调用flutter中的'lal'方法,传递参数字符串‘android’,将flutter返回的结果通过toast打印出来。
class SecondActivity : FlutterActivity()
lateinit var channel: MethodChannel
override fun configureFlutterEngine(flutterEngine: FlutterEngine)
super.configureFlutterEngine(flutterEngine)
channel = MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NATIVE)
override fun onCreate(savedInstanceState: Bundle?)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
btn.setOnClickListener
channel.invokeMethod("lal", "android", object : MethodChannel.Result
override fun notImplemented()
Toast.makeText(this@SecondActivity, "notImplemented", Toast.LENGTH_SHORT).show()
override fun error(errorCode: String?, errorMessage: String?, errorDetails: Any?)
Toast.makeText(this@SecondActivity, "error:$errorMessage", Toast.LENGTH_SHORT).show()
override fun success(result: Any?)
if (result != null)
Toast.makeText(this@SecondActivity, result as String, Toast.LENGTH_SHORT).show()
)
演示
以上是关于原生与Flutter通信的主要内容,如果未能解决你的问题,请参考以下文章