可以看如下图:

从上图中可以看到,方法调用请求的处理和响应,在
Android 中是通过 FlutterView,而在 iOS 中则是通过 FlutterViewController 进行注册的。FlutterView 与 FlutterViewController 为 Flutter 应用提供了一个画板,使得构建于Skia 之上的 Flutter通过绘制即可实现整个应用所需的视觉效果。因此,它们不仅是 Flutter应用的容器,同时也是 Flutter应用的入口,自然也是注册方法调用请求最合适的地方。
方法通道使用示例(打开应用市场)
//声明MethodChannel
const platform = MethodChannel('samples.mm/utils');
//处理按钮点击
handleButtonClick() async{
int result;
//异常捕获
try {
//异步等待方法通道的调用结果
result = await platform.invokeMethod('openAppMarket');
}
catch (e) {
result = -1;
}
print("Result:$result");
}
首先,我们来看看 Android 端的实现方式。在上一小结最后我提到,在 Android 平台,方法调用的处理和响应是在 Flutter 应用的入口,也就是在 MainActivity 中的 FlutterView 里实现的,因此我们需要打开 Flutter 的 Android 宿主 App,找到 ·MainActivity.java· 文件,并在其中添加相关的逻辑。调用方与响应方都是通过命名通道进行信息交互的,所以我们需要在 onCreate 方法中,创建一个与调用方 ·Flutter· 所使用的通道名称一样的 ·MethodChannel,并在其中设置方法处理回调,响应openAppMarket `方法,打开应用市场的 Intent。同样地,考虑到打开应用市场的过程可能会出错,我们也需要增加 try-catch 来捕获可能的异常:
protected void onCreate(Bundle savedInstanceState) {
...
//创建与调用方标识符一样的方法通道
new MethodChannel(getFlutterView(), "samples.mm/utils").setMethodCallHandler(
//设置方法处理回调
new MethodCallHandler() {
//响应方法请求
@Override
public void onMethodCall(MethodCall call, Result result) {
//判断方法名是否支持
if(call.method.equals("openAppMarket")) {
try {
//应用市场URI
Uri uri = Uri.parse("market://details?id=com.hangchen.example.flutter_module_page.host");
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//打开应用市场
activity.startActivity(intent);
//返回处理结果
result.success(0);
} catch (Exception e) {
//打开应用市场出现异常
result.error("UNAVAILABLE", "没有安装应用市场", null);
}
}else {
//方法名暂不支持
result.notImplemented();
}
}
});
}
现在,方法调用响应的 Android部分已经搞定,接下来我们来看一下 iOS 端的方法调用响应如何实现。在 iOS平台,方法调用的处理和响应是在 Flutter 应用的入口,也就是在 Applegate 中的rootViewController(即 FlutterViewController)里实现的,因此我们需要打开 Flutter 的 iOS 宿主 App,找到 AppDelegate.m 文件,并添加相关逻辑。与 Android 注册方法调用响应类似,我们需要在 didFinishLaunchingWithOptions:方法中,创建一个与调用方 Flutter 所使用的通道名称一样的 MethodChannel,并在其中设置方法处理回调,响应 openAppMarket 方法,通过 URL 打开应用市场:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//创建命名方法通道
FlutterMethodChannel* channel = [FlutterMethodChannel methodChannelWithName:@"samples.mm/utils" binaryMessenger:(FlutterViewController *)self.window.rootViewController];
//往方法通道注册方法调用处理回调
[channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) {
//方法名称一致
if ([@"openAppMarket" isEqualToString:call.method]) {
//打开App Store(本例打开微信的URL)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/xy/app/foo/id414478124"]];
//返回方法处理结果
result(@0);
} else {
//找不到被调用的方法
result(FlutterMethodNotImplemented);
}
}];
...
}