1.PlatformChannel概述
下面是PlatformChannel架构。
Flutter定义了三种不同类型的PlatformChannel,它们分别是:
- MethodChannel:用于传递方法调用,是比较常用的PlatformChannel。
- EventChannel: 用于传递事件。
- BasicMessageChannel:用于传递数据。
这几个PlatformChannel的用法都不难,本文会以比较常用的MethodChannel来进行举例。在此之前我们先要了解BinaryMessenger、Codec、Handler的概念。
BinaryMessenger
BinaryMessenger是PlatformChannel与Flutter端的通信的工具,其通信使用的消息格式为二进制格式数据,BinaryMessenger在Android中是一个接口,它的实现类为FlutterNativeView。
Codec
Codec是消息编解码器,主要用于将二进制格式的数据转化为Handler能够识别的数据,Flutter定义了两种Codec:MessageCodec和MethodCodec。MessageCodec用于二进制格式数据与基础数据之间的编解码,BasicMessageChannel所使用的编解码器是MessageCodec。MethodChannel和EventChannel所使用的编解码均为MethodCodec。
Handler
Flutter定义了三种类型的Handler,它们与PlatformChannel类型一一对应,分别是MessageHandler、MethodHandler、StreamHandler。在使用PlatformChannel时,会为它注册一个Handler,PlatformChannel会将该二进制数据通过Codec解码为转化为Handler能够识别的数据,并交给Handler处理。当Handler处理完消息之后,会通过回调函数返回result,将result通过编解码器编码为二进制格式数据,通过BinaryMessenger发送回Flutter端。
MethodChannel可以实现Flutter调用Android,也可以实现Android调用Flutter,这里分别来进行举例。
2.Flutter调用Android
先在MainActivity中实现功能,如下所示。
package com.example.platform_channel;
import android.app.AlertDialog;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugins.GeneratedPluginRegistrant;
public class MainActivity extends FlutterActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);//1
MethodChannel methodChannel = new MethodChannel(getFlutterView(), "com.example.platform_channel/dialog");//2
methodChannel.setMethodCallHandler(new MethodChannel.MethodCallHandler() {//3
@Override
public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
if ("dialog".equals(methodCall.method)) {
if (methodCall.hasArgument("content")) {
showAlertDialog();
result.success("弹出成功");
} else {
result.error("error", "弹出失败", "content is null");
}
} else {
result.notImplemented();
}
}
private void showAlertDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setPositiveButton("确定", null);
builder.setTitle("Flutter调用Android");
builder.show();
}
});
}
}
在main.dart中加入如下代码。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
static const platformChannel =
const MethodChannel('com.example.platform_channel/dialog');//1
@override
Widget build(BuildContext context) {
return MaterialApp(
title: "Flutter Demo",
home: Scaffold(
appBar: AppBar(
title: Text("Flutter调用Android"),
),
body: Padding(
padding: EdgeInsets.all(40.0),
child: RaisedButton(
child: Text("调用Dialog"),
onPressed: () {
showDialog("Flutter调用AlertDialog");
},
),
),
),
);
}
void showDialog(String content) async {
var arguments = Map();
arguments['content'] = content;
try {
String result = await platformChannel.invokeMethod('dialog', arguments);//2
print('showDialog ' + result);
} on PlatformException catch (e) {
print('showDialog ' + e.code + e.message + e.details);
} on MissingPluginException catch (e) {
print('showDialog ' + e.message);
}
}
}
运行程序,效果如下: