Flutter development mixed (interactive communication)

Part I we introduced the Flutter module is integrated into an existing project, then we look at the interaction between Native problem with Flutter.

Alternate communication

Flexible messaging communication dependent manner between the native and Flutter:

1, Flutter section through the platform channel message transmitted to the host environment in which their applications (native application).

2, the host platform environment by listening to the channel, receiving a message. It then calls the API platform, Flutter response message sent.

Flutter take the initiative to call the host environment

In MethodChannel Flutter by the API can send a message with respect to the method, the hosting environment iOS accept calls and returns the results of the method FlutterMethodChannel.

Flutter need to introduce a services.dartmodule can use MethodChannel

1
import 'package:flutter/services.dart';

Flutter in the calling code

1
const methodChannel = const MethodChannel("com.pages.flutter/call_native");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
RaisedButton(
child: Text("call_native_method_no_params"),
onPressed: (){
methodChannel.invokeMethod("call_native_method_no_params",null);
},
),
RaisedButton(
child: Text("call_native_method_params"),
onPressed: (){
Map<String,String> params = {"params":"flutter params"};
methodChannel.invokeMethod("call_native_method_params",params);
},
),
RaisedButton(
child: Text("call_native_method_native_result_callback"),
onPressed: (){
_nativeCallbackWithParams();
},
),
Text(_content,style: TextStyle(color: Colors.red),)
1
2
3
4
5
6
7
8
9
10
11
12
Future<Null> _nativeCallbackWithParams() async{
dynamic result;
try {
result = await methodChannel.invokeMethod(
"call_native_method_native_result_callback", null);
} on PlatformException catch (e) {
result = "Failed to get params: '${e.message}'.";
}
setState(() {
_content = result;
});
}

Calling code in iOS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
FlutterViewController* flutterViewController = [[FlutterViewController alloc] init];
flutterViewController.fd_prefersNavigationBarHidden = YES;
FlutterMethodChannel * messageChannel = [FlutterMethodChannel methodChannelWithName:@"com.pages.flutter/call_native" binaryMessenger:flutterViewController];
[messageChannel setMethodCallHandler:^(FlutterMethodCall * _Nonnull call, FlutterResult _Nonnull result) {
NSLog(@"flutter call native:n method=%@ n arguments = %@",call.method,call.arguments);
if ([call.method isEqualToString:@"call_native_method_native_result_callback"]) {
if (result) {
result(@"flutter hello");
} 大专栏  Flutter 混合开发 (交互通信)
}else if([call.method isEqualToString:@"call_native_method_pop_flutter_nav"]){
[weakSelf.navigationController popViewControllerAnimated:YES];
}
}];
[self.navigationController pushViewController:flutterViewController animated:YES];

Respectively facie console output:

1
2
3
flutter call native:
method=call_native_method_no_params
arguments = (null)
1
2
3
4
5
flutter call native:
method=call_native_method_params
arguments = {
params = "flutter params";
}

The third event will be displayed flutter hello to the value returned by the host environment Flutter page.

注意: 这里有个设计上的细节,上节提到过就是导航栏的问题,因为宿主环境有个导航栏,而 Flutter 自身也有导航栏,出现了矛盾,到底我们应该保留宿主环境的,还是 Flutter 页面使用自身,隐藏宿主环境的导航栏。我个人觉得后则更合理,Flutter 页面更了解自己导航栏具体功能、主题、交互及显示,我们只需要处理点击返回按钮 pop 回到宿主环境中,如下:

1
2
3
4
appBar: AppBar(
title: Text('Flutter Page') ,
leading: IconButton(icon: Icon(Icons.arrow_back_ios), onPressed:()=>methodChannel.invokeMethod("call_native_method_pop_flutter_nav",null)),
),

我们只需要在宿主环境中监听到该事件后调用导航的 pop 功能。

宿主环境主动调用 Flutter

一般可以用作宿主环境为 Flutter 提供参数

EventChannel 是 Flutter 监听宿主环境的 API ,FlutterEventChannel 是 iOS 宿主环境与 Flutter 交互平台通道的 API 。

Flutter 代码片段

1
const EventChannel eventChannel = const EventChannel('com.pages.flutter/call_flutter');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

void initState(){
super.initState();
eventChannel.receiveBroadcastStream(12345).listen(_onEvent,onError: _onError);
}

void _onEvent(Object event){
setState(() {
_content = event.toString();
});
}

void _onError(Object error){
setState(() {
_content = error.toString();
});
}

iOS 宿主环境代码片段

1
2
3
NSString *eventChannelName = @"com.pages.flutter/call_flutter";
FlutterEventChannel *eventChannel = [FlutterEventChannel eventChannelWithName:eventChannelName binaryMessenger:flutterViewController];
[eventChannel setStreamHandler:self];
1
2
3
4
5
6
7
8
9
10
- (FlutterError *)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)events {
if (events) {
events(@"hi flutter");
}
return nil;
}

- (FlutterError* _Nullable)onCancelWithArguments:(id _Nullable)arguments {
return nil;
}

两端交互通信方式就是这样的,这里也只是介绍了他们通信的方式,具体如何优雅的封装、规范交互流程还需要我们自己去考虑下。

Guess you like

Origin www.cnblogs.com/liuzhongrong/p/12288934.html