Flutter与Android通信开发指南

本文详细介绍了Flutter应用与Android原生代码之间的通信方法,包括MethodChannel和EventChannel的使用,强调了保持两端Channel名字和编解码器的一致性。示例代码展示了如何在Native端和Dart端设置消息处理器,进行消息传递与处理。此外,提供了资源链接供读者进一步学习和下载相关源码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • String name - Channel的名字,要和Native端保持一致;

  • MessageCodec<T> codec - 消息的编解码器,要和Native端保持一致,有四种类型的实现具体可以参考Native端的介绍;

setMessageHandler方法原型

void setMessageHandler(Future handler(T message))

  • Future<T> handler(T message) - 消息处理器,配合BinaryMessenger完成消息的处理;

在创建好BasicMessageChannel后,如果要让其接收Native发来的消息,则需要调用它的setMessageHandler方法为其设置一个消息处理器。

send方法原型

Future send(T message)

  • T message - 要传递给Native的具体信息;

  • Future<T> - 消息发出去后,收到Native回复的回调函数;

在创建好BasicMessageChannel后,如果要向Native发送消息,可以调用它的send方法向Native传递数据。

import ‘package:flutter/services.dart’;

static const BasicMessageChannel _basicMessageChannel =

const BasicMessageChannel(‘BasicMessageChannelPlugin’, StringCodec());

//使用BasicMessageChannel接受来自Native的消息,并向Native回复

_basicMessageChannel

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

setState(() {

showMessage = message;

});

return “收到Native的消息:” + message;

}));

//使用BasicMessageChannel向Native发送消息,并接受Native的回复

String response;

try {

response = await _basicMessageChannel.send(value);

} on PlatformException catch (e) {

print(e);

}

实例源码下载

MethodChannel用法

Native端:

构造方法原型

//会构造一个StandardMethodCodec.INSTANCE类型的MethodCodec

MethodChannel(BinaryMessenger messenger, String name)

//或

MethodChannel(BinaryMessenger messenger, String name, MethodCodec codec)

  • BinaryMessenger messenger - 消息信使,是消息的发送与接收的工具;

  • String name - Channel的名字,也是其唯一标识符;

  • MethodCodec codec - 用作MethodChannel的编解码器;

setMethodCallHandler方法原型

setMethodCallHandler(@Nullable MethodChannel.MethodCallHandler handler)

  • @Nullable MethodChannel.MethodCallHandler handler - 消息处理器,配合BinaryMessenger完成消息的处理;

在创建好MethodChannel后,需要调用它的setMessageHandler方法为其设置一个消息处理器,以便能加收来自Dart的消息。

MethodChannel.MethodCallHandler原型

public interface MethodCallHandler {

void onMethodCall(MethodCall var1, MethodChannel.Result var2);

}

  • onMethodCall(MethodCall call, MethodChannel.Result result) - 用于接受消息,call是消息内容,它有两个成员变量String类型的call.method表示调用的方法名,Object 类型的call.arguments表示调用方法所传递的入参;MethodChannel.Result result是回复此消息的回调函数提供了result.successresult.errorresult.notImplemented方法调用;

public class MethodChannelPlugin implements MethodCallHandler {

private final Activity activity;

/**

  • Plugin registration.

*/

public static void registerWith(FlutterView flutterView) {

MethodChannel channel = new MethodChannel(flutterView, “MethodChannelPlugin”);

MethodChannelPlugin instance = new MethodChannelPlugin((Activity) flutterView.getContext());

channel.setMethodCallHandler(instance);

}

private MethodChannelPlugin(Activity activity) {

this.activity = activity;

}

@Override

public void onMethodCall(MethodCall call, Result result) {

switch (call.method) {//处理来自Dart的方法调用

case “showMessage”:

showMessage(call.arguments());

result.success(“MethodChannelPlugin收到:” + call.arguments);//返回结果给Dart

break;

default:

result.notImplemented();

}

}

/**

  • 展示来自Dart的数据

  • @param arguments

*/

private void showMessage(String arguments) {

if (activity instanceof IShowMessage) {

((IShowMessage) activity).onShowMessage(arguments);

}

Toast.makeText(activity, arguments, Toast.LENGTH_SHORT).show();

}

}

实例源码下载

Dart端:

构造方法原型

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

  • String name - Channel的名字,要和Native端保持一致;

  • MethodCodec codec - 消息的编解码器,默认是StandardMethodCodec,要和Native端保持一致;

invokeMethod方法原型

Future invokeMethod(String method, [ dynamic arguments ])

  • String method:要调用Native的方法名;

  • [ dynamic arguments ]:调用Native方法传递的参数,可不传;

import ‘package:flutter/services.dart’;

static const MethodChannel _methodChannelPlugin =

const MethodChannel(‘MethodChannelPlugin’);

String response;

try {

response = await _methodChannelPlugin.invokeMethod(‘send’, value);

} on PlatformException catch (e) {

print(e);

}

EventChannel用法

Native端:

构造方法原型

//会构造一个StandardMethodCodec.INSTANCE类型的MethodCodec

EventChannel(BinaryMessenger messenger, String name)

//或

EventChannel(BinaryMessenger messenger, String name, MethodCodec codec)

  • BinaryMessenger messenger - 消息信使,是消息的发送与接收的工具;

  • String name - Channel的名字,也是其唯一标识符;

  • MethodCodec codec - 用作EventChannel的编解码器;

setStreamHandler方法原型

void setStreamHandler(EventChannel.StreamHandler handler)

EventChannel.StreamHandler handler - 消息处理器,配合BinaryMessenger完成消息的处理;

在创建好EventChannel后,如果要让其接收Dart发来的消息,则需要调用它的setStreamHandler方法为其设置一个消息处理器。

EventChannel.StreamHandler原型

public interface StreamHandler {

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

void onCancel(Object o);

}

  • void onListen(Object args, EventChannel.EventSink eventSink) - Flutter Native监听事件时调用,Object args是传递的参数,EventChannel.EventSink eventSink是Native回调Dart时的会回调函数,eventSink提供successerrorendOfStream三个回调方法分别对应事件的不同状态;

  • void onCancel(Object o) - Flutter取消监听时调用;

public class EventChannelPlugin implements EventChannel.StreamHandler {

private List<EventChannel.EventSink> eventSinks = new ArrayList<>();

static EventChannelPlugin registerWith(FlutterView flutterView) {

EventChannelPlugin plugin = new EventChannelPlugin();

new EventChannel(flutterView, “EventChannelPlugin”).setStreamHandler(plugin);

return plugin;

}

void sendEvent(Object params) {

for (EventChannel.EventSink eventSink : eventSinks) {

eventSink.success(params);

}

}

@Override

public void onListen(Object args, EventChannel.EventSink eventSink) {

eventSinks.add(eventSink);

}

@Override

public void onCancel(Object o) {

}

}

实例源码下载

Dart端:

构造方法原型

const EventChannel(this.name, [this.codec = const StandardMethodCodec()]);

  • String name - Channel的名字,要和Native端保持一致;

  • MethodCodec codec - 消息的编解码器,默认是StandardMethodCodec,要和Native端保持一致;

receiveBroadcastStream方法原型

Stream receiveBroadcastStream([ dynamic arguments ])

  • dynamic arguments - 监听事件时向Native传递的数据;

初始化一个广播流用于从channel中接收数据,它返回一个Stream接下来需要调用Stream的listen方法来完成注册,另外需要在页面销毁时调用Stream的cancel方法来取消监听;

import ‘package:flutter/services.dart’;

static const EventChannel _eventChannelPlugin =

EventChannel(‘EventChannelPlugin’);

StreamSubscription _streamSubscription;

@override

void initState() {

_streamSubscription=_eventChannelPlugin

.receiveBroadcastStream()

.listen(_onToDart, onError: _onToDartError);

super.initState();

}

@override

void dispose() {

if (_streamSubscription != null) {

_streamSubscription.cancel();

_streamSubscription = null;

}

super.dispose();

}

void _onToDart(message) {

setState(() {

showMessage = message;

});

}

void _onToDartError(error) {

print(error);

}

实例源码下载

1. 初始化Flutter时Native向Dart传递数据


init-data-to-js

在Flutter的API中提供了Native在初始化Dart页面时传递数据给Dart的方式,这种传递数据的方式比下文中所讲的其他几种传递数据的方式发生的时机都早。

因为很少有资料介绍这种方式,所以可能有很多同学还不知道这种方式,不过不要紧,接下来我就向大家介绍如何使用这种方式来传递数据给Dart。

Android向Flutter传递初始化数据initialRoute

Flutter允许我们在初始化Flutter页面时向Flutter传递一个String类型的initialRoute参数,从参数名字它是用作路由名的,但是既然Flutter给我们开了这个口子,那我们是不是可以搞点事情啊,传递点我们想传的其他参数呢,比如:

FragmentTransaction tx = getSupportFragmentManager().beginTransaction();

tx.replace(R.id.someContainer, Flutter.createFragment(“{name:‘devio’,dataList:[‘aa’,‘bb’,''cc]}”));

tx.commit();

//or

View flutterView = Flutter.createView(

MainActivity.this,

getLifecycle(),

“route1”

);

FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600, 800);

layout.leftMargin = 100;

layout.topMargin = 200;

addContentView(flutterView, layout);

然后在Flutter module通过如下方式获取:

import ‘dart:ui’;//要使用window对象必须引入

String initParams=window.defaultRouteName;

//序列化成Dart obj 敢你想干的

通过上述方案的讲解是不是给大家分享了一个新的思路呢。

接下来,我们先来看一下如何在Android上来传递这些初始化数据。

2. Native到Dart的通信(Native发送数据给Dart)


在Flutter 中Native向Dart传递消息可以通过BasicMessageChannelEventChannel都可以实现:

通过BasicMessageChannel的方式

BasicMessageChannel

如何实现?

通过EventChannel的方式

EventChannel

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!

264390797)]

[外链图片转存中…(img-gGVCGKCB-1712264390797)]

[外链图片转存中…(img-bbJbQDyY-1712264390798)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

资源分享

  • 最新大厂面试专题

这个题库内容是比较多的,除了一些流行的热门技术面试题,如Kotlin,数据库,Java虚拟机面试题,数组,Framework ,混合跨平台开发,等

[外链图片转存中…(img-tCIpZqD0-1712264390798)]

  • 对应导图的Android高级工程师进阶系统学习视频
    最近热门的,NDK,热修复,MVVM,源码等一系列系统学习视频都有!

[外链图片转存中…(img-4WItulrK-1712264390798)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值