flutter
可以native之间可以通过Platform Channels APIs进行通信,API主要有以下三种:
- [MethodChanel]:用于传递方法调用(method invocation)
- [EventChannel]:用于事件流的发送(event streams)
- [MessageChannel]:用于传递字符串和半结构化的消息
其中EventChannel用于从native向flutter发送通知事件,例如flutter通过其监听Android的重力感应变化等。与MethodChannel不同,EventChannel是native到flutter的单向调用,调用是多播(一对多)的,可以类比成Android的Brodcast。
1. EventChannel的基本流程
我们照例先看一下API使用的基本流程:
- [native]EventChannel#setStreamHandler注册Handler实现
- [native]EventChannel初始化结束后,在StreamHandler#onLister回调中获取EventSink引用并保存
- [flutter]EventChannel#receiveBroadcastStream注册listener,建立监听
- [native]使用EventSink#sucess发送通知事件
- [flutter]接受到事件通知
- [native]通知结束时调用endOfStream结束
2.代码实现
flutter端
- 创建EventChannel,注册“包名/标识符”的channel名
- 通过StreamSubscription#listen注册listener,其中cancelOnError参数表示遇到错误时是否自动结束监听
class _MyHomePageState extends State<MyHomePage> {
static const EventChannel _channel = const EventChannel('com.example.eventchannel/interop');
StreamSubscription _streamSubscription;
String _platformMessage;
void _enableEventReceiver() {
_streamSubscription = _channel.receiveBroadcastStream().listen(
(dynamic event) {
print('Received event: $event');
setState(() {
_platformMessage = event;
});
},
onError: (dynamic error) {
print('Received error: ${error.message}');
},
cancelOnError: true);
}
void _disableEventReceiver() {
if (_streamSubscription != null) {
_streamSubscription.cancel();
_streamSubscription = null;
}
}
@override
initState() {
super.initState();
_enableEventReceiver();
}
@override
void dispose() {
super.dispose();
_disableEventReceiver();
}
调用StreamSubscriptoin#cancel时,监听被取消。
native(android)端
android需要完成以下功能
- 通过EventChannel#setStreamHandler注册Handler实现
- 初始化完成后,获取eventSink引用并保存
- eventSink发送事件通知
- 通知结束时调用event#endOfStream,此时onCancel会被调用
- 必要时,可通过evnetSink#error发送错误通知,flutter的StreamSubscription#onError会收到通知
class MainActivity: FlutterActivity() {
private lateinit var channel: EventChannel
var eventSink: EventSink? = null
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
GeneratedPluginRegistrant.registerWith(flutterEngine)
channel = EventChannel(flutterEngine.dartExecutor.binaryMessenger, "com.example.eventchannel/interop")
channel.setStreamHandler(
object : StreamHandler {
override fun onListen(arguments: Any?, events: EventSink) {
eventSink = events
Log.d("Android", "EventChannel onListen called")
Handler().postDelayed({
eventSink?.success("Android")
//eventSink?.endOfStream()
//eventSink?.error("error code", "error message","error details")
}, 500)
}
override fun onCancel(arguments: Any?) {
Log.w("Android", "EventChannel onCancel called")
}
})
}
}