一篇看懂Android与Flutter之间的通信,吃一堑长一智
前面讲了Android与flutter通信的一些基础知识,下面就进入正题,来看Android如何与flutter进行通信。
Android与Flutter之间的通信共有四种实现方式。
- 由于在初始化flutter页面时会传递一个字符串——route,因此我们就可以拿route来做文章,传递自己想要传递的数据。该种方式仅支持单向数据传递且数据类型只能为字符串,无返回值。
- 通过
EventChannel来实现,EventChannel仅支持数据单向传递,无返回值。 - 通过
MethodChannel来实现,MethodChannel支持数据双向传递,有返回值。 - 通过
BasicMessageChannel来实现,BasicMessageChannel支持数据双向传递,有返回值。
下面就来看一下这几种方式的使用。
3.1、初始化时传值
主要是利用了创建flutter页面传递的route来做文章,笔者认为该种方式属于取巧,但还是可以用来传递数据。它的使用很简单,代码如下。
首先来看Android代码。
//第三个参数可以换成我们想要字符串。
FlutterView flutterView = Flutter.createView(this, getLifecycle(), “route”);
在flutter中,我们只需要通过下面代码来获取值即可。
void main() => runApp(MyApp(
initParams: window.defaultRouteName,
));
class MyApp extends StatelessWidget {
final String initParams;//既是前面传递的值——route
MyApp({Key key, @required this.initParams}) : super(key: key);
@override
Widget build(BuildContext context) {…}
}
通过该种方式就可以在初始化flutter时,Android给flutter传递数据。由于runApp仅会调用一次,所以该种方式只能传递一次数据且数据只能是字符串。
使用
window的相关API需要导入包dart:ui
3.2、EventChannel
EventChannel是一种native向flutter发送数据的单向通信方式,flutter无法返回任何数据给native。主要用于native向flutter发送手机电量变化、网络连接变化、陀螺仪、传感器等。它的使用方式如下。
首先来看Android代码。
public class EventChannelPlugin implements EventChannel.StreamHandler {
private static final String TAG = EventChannelPlugin.class.getSimpleName();
private EventChannel.EventSink eventSink;
private Activity activity;
static EventChannelPlugin registerWith(FlutterView flutterView) {
EventChannelPlugin plugin = new EventChannelPlugin(flutterView);
new EventChannel(flutterView, “EventChannelPlugin”).setStreamHandler(plugin);
return plugin;
}
private EventChannelPlugin(FlutterView flutterView) {
this.activity = (Activity) flutterView.getContext();
}
void send(Object params) {
if (eventSink != null) {
eventSink.success(params);
}
}
void sendError(String str1, String str2, Object params) {
if (eventSink != null) {
eventSink.error(str1, str2, params);
}
}
void cancel() {
if (eventSink != null) {
eventSink.endOfStream();
}
}
//第一个参数为flutter初始化EventChannel时返回的值,仅此一次
@Override
public void onListen(Object o, EventChannel.EventSink eventSink) {
this.eventSink = eventSink;
Log.i(TAG, “eventSink:” + eventSink);
Log.i(TAG, “Object:” + o.toString());
Toast.makeText(activity, “onListen——obj:” + o, Toast.LENGTH_SHORT).show();
}
@Override
public void onCancel(Object o) {
Log.i(TAG, “onCancel:” + o.toString());
Toast.makeText(activity, “onCancel——obj:” + o, Toast.LENGTH_SHORT).show();
this.eventSink = null;
}
}
笔者对Android端代码做了一个简单的封装,还是很好理解的。下面就来看flutter代码实现。
class _MyHomePageState extends State {
EventChannel _eventChannelPlugin = EventChannel(“EventChannelPlugin”);
StreamSubscription _streamSubscription;
@override
void initState() {
_streamSubscription = _eventChannelPlugin
//[“abc”, 123, “你好”]对应着Android端onListen方法的第一个参数,可不传值
.receiveBroadcastStream([“abc”, 123, “你好”])
.listen(_onToDart, onError: _onToDartError, onDone: _onDone);
super.initState();
}
@override
void dispose() {
if (_streamSubscription != null) {
_streamSubscription.cancel();
_streamSubscription = null;
}
super.dispose();
}
//native端发送正常数据
void _onToDart(message) {
print(message);
}
//当native出错时,发送的数据
void _onToDartError(error) {
print(error);
}
//当native发送数据完成时调用的方法,每一次发送完成就会调用
void _onDone() {
print(“消息传递完毕”);
}
@override
Widget build(BuildContext context) {…}
}
上面就是通过EventChannel来进行通信的代码实现,调用EventChannelPlugin的send方法就能给flutter发送数据。
3.3、MethodChannel
MethodChannel是一种native与flutter之间互相发送数据的通信方式,顾名思义,通过MethodChannel就能调用native与flutter中相对应的方法,该种方式有返回值。它的使用方式如下。
首先来看Android端的代码实现。
public class MethodChannelPlugin implements MethodChannel.MethodCallHandler {
private Activity activity;
private MethodChannel channel;
public static MethodChannelPlugin registerWith(FlutterView flutterView) {
MethodChannel channel = new MethodChannel(flutterView, “MethodChannelPlugin”);
MethodChannelPlugin methodChannelPlugin = new MethodChannelPlugin((Activity) flutterView.getContext(), channel);
channel.setMethodCallHandler(methodChannelPlugin);
return methodChannelPlugin;
}
private MethodChannelPlugin(Activity activity, MethodChannel channel) {
this.activity = activity;
this.channel = channel;
}
//调用flutter端方法,无返回值
public void invokeMethod(String method, Object o) {
channel.invokeMethod(method, o);
}
//调用flutter端方法,有返回值
public void invokeMethod(String method, Object o, MethodChannel.Result result) {
channel.invokeMethod(method, o, result);
}
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
switch (methodCall.method) {
case “send”😕/返回的方法名
//给flutter端的返回值
result.success(“MethodChannelPlugin收到:” + methodCall.arguments);
Toast.makeText(activity, methodCall.arguments + “”, Toast.LENGTH_SHORT).show();
if (activity instanceof FlutterAppActivity) {
((FlutterAppActivity) activity).showContent(methodCall.arguments);
}
break;
default:
result.notImplemented();
break;
}
}
}
笔者对Android端代码做了一个简单的封装,还是很好理解的。下面就来看flutter代码实现。
class _MyHomePageState extends State {
MethodChannel _methodChannel = MethodChannel(“MethodChannelPlugin”);
@override
void initState() {
_methodChannel.setMethodCallHandler((handler) => Future(() {
print("_methodChannel:${handler}");
//监听native发送的方法名及参数
switch (handler.method) {
case “send”:
_send(handler.arguments);//handler.arguments表示native传递的方法参数
break;
}
}));
super.initState();
}
//native调用的flutter方法
void _send(arg) {
setState(() {
_content = arg;
});
}
String _resultContent = “”;
//flutter调用native的相应方法
void _sendToNative() {
Future future =
_methodChannel.invokeMethod(“send”, _controller.text);
future.then((message) {
setState(() {
//message是native返回的数据
_resultContent = “返回值:” + message;
});
});
}
@override
Widget build(BuildContext context) {…}
}
最后
都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。
技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;
我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
《Android架构视频+BAT面试专题PDF+学习笔记》



网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。
题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。
更多推荐



所有评论(0)