写点什么

Flutter 混合开发 (三):Android 与 Flutter 之间通信详细指南

用户头像
Android架构
关注
发布于: 刚刚

Future<T> send(T?message)


参数 message 为要传递的参数。Future 为发送消息后等待 Native 回复的回调函数。

BasicMessageChannel 实战:Android 端和 Flutter 端相互发送消息,并且在收到消息后返回对方信息
Android 端代码:

//初始化 BasicMessageChannel


BasicMessageChannel<String> basicMessageChannel = new BasicMessageChannel<>(flutterView,


"BasicMessageChannelPlugin",StringCodec.INSTANCE);


//接受消息


basicMessageChannel.setMessageHandler((message, reply) -> {


mTvDart.setText(message);


reply.reply("收到 dart 数据:接受成功");


});


//发送消息


basicMessageChannel.send(message, reply -> mTvDart.setText(reply));

Dart 端代码:

//初始化 BasicMessageChannel


static const BasicMessageChannel<String> _basicMessageChannel =


BasicMessageChannel("BasicMessageChannelPlugin", StringCodec());


// 接受消息


void handleBasicMessageChannel() {


_basicMessageChannel


.setMessageHandler((String message) => Future<String>(() {


setState(() {


showMessage = message;


});


return "收到 Native 的消息:接受成功";


}));


}


//发送消息


response = await _basicMessageChannel.send(_controller.text);


setState(() {


showMessage = response;


});


最后效果为下图,红色分割线上部分为 Native 页面,下部分为 Flutter 页面。



MethodChannel


================================================================================


使用 MethodChannel 相关方法的参数类型及含义和 BasicMessageChannel 的参数含义都是相同的,下面就不一一解释了。

Androd 端相关方法:

MethodChannel(BinaryMessenger messenger, String name)


MethodChannel(BinaryMessenger messenger, String name, MethodCodec codec)


第一个构造函数会构造一个 StandardMethodCodec.INSTANCE 类型的 MethodCodec。MethodCodec 定义了两种类型:JSONMethodCodec 和 StandardMethodCodec。


如果想接受来自 Dart 端的消息则使用:


setMethodCallHandler(@Nullable?MethodChannel.MethodCallHandler handler)


MethodCallHandler 为接口,回调方法为:


public interface MethodCallHandler {


void onMethodCall(MethodCall call, MethodChannel.Result result);


}


call 参数有两个成员变量,String 类型的 call.method 表示调用的方法名,Object 类型的 call.arguments 表示调用方法所传递的入参。result 是回复此消息的回调函数提供了 result.success,result.error,result.notImplemented 方法调用。


发送消息主动调用 Dart 代码则使用 invokeMethod 方法


invokeMethod(@NonNull String method, @Nullable Object arguments)


invokeMethod(String method, @Nullable Object arguments, Result callback)


第二个方法多了一个 callback,它是用来接受 Dart 端收到消息后的回复信息。


public interface Result {


void success(@Nullable Object result);


void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails);


void notImplemented();


}

Dart 端相关方法:

const?MethodChannel(this.name, [this.codec =?const?StandardMethodCodec()])


构造函数默认是使用 StandardMethodCodec 编解码器。


通过 setMethodCallHandler 方法接受来自 Native 的方法调用,通过 invokeMethod 方法调用 Native 端的方法。


void setMethodCallHandler(Future<dynamic>?handler(MethodCall?call))


Future<T> invokeMethod<T>(String?method, [?dynamic?arguments?])

MethodChannel 实战: Native 端调用 Dart 端的 getPlatform 方法返回当前的 os 平台,Dart 端调用 Native 端的 getBatteryLevel 方法获取当前手机电量。
Android 端代码:

//初始化 MethodChannel


MethodChannel methodChannel = new MethodChannel(flutterView, "MethodChannelPlugin");


mBtnTitle.setOnClickListener(new View.OnClickListener() {


@Override


public void onClick(View v) {


//调用 dart 端 getPlatform 方法


methodChannel.invokeMethod("getPlatform", null, new MethodChannel.Result() {


@Override


public void success(@Nullable Object result) {


mTvDart.setText(result.toString());


}


@Override


public void error(String errorCode, @Nullable String errorMessage, @Nullable Object errorDetails) {


mTvDart.setText(errorCode + "==" + errorMessage);


}


@Override


public void notImplemented() {


mTvDart.setText("未实现 getPlatform 方法");


}


});


}


});


//接受 dart 的调用


methodChannel.setMethodCallHandler((call, result) -> {


switch (call.method) {


case "getBatteryLevel":


int batteryLevel = getBatteryLevel();


if (batteryLevel != -1) {


result.success("电量为:" + batteryLevel);


} else {


result.error("1001", "调用错误", null);


}


break;


default:


result.notImplemented();


break;


}


});

Dart 端代码:

// receive


void handleMethodChannelReceive() {


Future<dynamic> platformCallHandler(M


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


ethodCall call) async {


switch (call.method) {


case "getPlatform":


return getPlatformName(); //调用 success 方法


// return PlatformException(code: '1002',message: "出现异常"); //调用 error


break;


}


}


_methodChannel.setMethodCallHandler(platformCallHandler);


// _methodChannel.setMethodCallHandler(null); //调用 notImplemented


}


//send


void handleMethodChannelSend() async {


try {


response = await _methodChannel.invokeMethod("getBatteryLevel");


print(response);


setState(() {


showMessage = response;


});


} catch (e) {


//捕获 error 和 notImplemented 异常


setState(() {


showMessage = e.message;


});


}


}


当我们在使用 setMethodCallHandler 接受到 native 的消息时,直接调用相关方法即可调用 Native 端的 success 回调。


如果直接抛异常如 PlatformException,那么就调用 Native 端的 error 回调。


PlatformException(code:?'1002',message:?"出现异常")


如果我们直接设置 handler 为 null


_methodChannel.setMethodCallHandler(null);


那么就会调用 Native 端的 notImplemented 方法回调。


同理我们在 Dart 端使用 invokeMethod 方法是,需要进行异常捕获以便于我们接受到 Native 端调用的 error 和 notImplemented 方法回调。


最后效果为下图,红色分割线上部分为 Native 页面,下部分为 Flutter 页面。



EventChannel


===============================================================================


EventChannel 内部实现原理其实也是通过 MethodChannel 来完成的。

Android 端相关代码:

EventChannel(BinaryMessenger messenger, String name)


EventChannel(BinaryMessenger messenger, String name, MethodCodec codec)


同样的,也是两个构造,默认 codec 为 StandardMethodCodec,EventChannel 和 MethodChannel 的 codec 都属于 MethodCodec 范畴。


通过 setStreamHandler 来监听 Dart 端发送的消息,


void?setStreamHandler(EventChannel.StreamHandler?handler)


其中 handler 是一个接口:


public interface StreamHandler {


void onListen(Object args, EventChannel.EventSink eventSink);


void onCancel(Object o);


}

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Flutter混合开发(三):Android与Flutter之间通信详细指南