Flutter与原生交互使用Platform Channel。Flutter定义了三种不同类型的Channel,它们分别是: :::info BasicMessageChannel:用于传递字符串和半机构化的信息(双向有返回值) ::: :::warning MethodChannel:用于传递方法调用(双向有返回值) :::

EventChannel:用于数据流(event streams)的通信(仅支持数据单向传递,无返回值)

三种Channel之间相互独立、各有用途,但是在设计上非常相近。每种Channel均有三个变量: :::warning name:String类型,代表Channel的名字,也是其唯一标识符
messager:BinaryMessager类型,代表消息信使,是消息的发送与接收的工具
codec:MessageCodec类型或MethodCodec类型,代表消息的编解码器 :::

MethodChannel

1、Flutter跳转到原生且携带参数

实现插件

  1. public class FlutterPluginJumpToAct implements MethodChannel.MethodCallHandler {
  2. public static String CHANNEL = "com.jzhu.jump/plugin";
  3. static MethodChannel channel;
  4. private Activity activity;
  5. private FlutterPluginJumpToAct(Activity activity) {
  6. this.activity = activity;
  7. }
  8. public static void registerWith(PluginRegistry.Registrar registrar) {
  9. channel = new MethodChannel(registrar.messenger(), CHANNEL);
  10. FlutterPluginJumpToAct instance = new FlutterPluginJumpToAct(registrar.activity());
  11. //setMethodCallHandler在此通道上接收方法调用的回调
  12. channel.setMethodCallHandler(instance);
  13. }
  14. @Override
  15. public void onMethodCall(MethodCall call, MethodChannel.Result result) {
  16. //通过MethodCall可以获取参数和方法名,然后再寻找对应的平台业务,本案例做了2个跳转的业务
  17. //接收来自flutter的指令oneAct
  18. if (call.method.equals("oneAct")) {
  19. //跳转到指定Activity
  20. Intent intent = new Intent(activity, OneActivity.class);
  21. activity.startActivity(intent);
  22. //返回给flutter的参数
  23. result.success("success");
  24. }
  25. //接收来自flutter的指令twoAct
  26. else if (call.method.equals("twoAct")) {
  27. //解析参数
  28. String text = call.argument("flutter");
  29. //带参数跳转到指定Activity
  30. Intent intent = new Intent(activity, TwoActivity.class);
  31. intent.putExtra(TwoActivity.VALUE, text);
  32. activity.startActivity(intent);
  33. //返回给flutter的参数
  34. result.success("success");
  35. }
  36. else {
  37. result.notImplemented();
  38. }
  39. }
  40. }

插件注册

需要在继承了FlutterActivity中的Activity中注册

  1. public class MainActivity extends FlutterActivity {
  2. @Override
  3. protected void onCreate(Bundle savedInstanceState) {
  4. super.onCreate(savedInstanceState);
  5. GeneratedPluginRegistrant.registerWith(this);
  6. registerCustomPlugin(this);
  7. }
  8. private static void registerCustomPlugin(PluginRegistry registrar) {
  9. FlutterPluginJumpToAct.registerWith(registrar.registrarFor(FlutterPluginJumpToAct.CHANNEL));
  10. FlutterPluginCounter.registerWith(registrar.registrarFor(FlutterPluginCounter.CHANNEL));
  11. }
  12. }

带参数跳转

  1. //获取到插件与原生的交互通道
  2. static const jumpPlugin = const MethodChannel('com.jzhu.jump/plugin');
  3. Future<Null> _jumpToNative() async {
  4. String result = await jumpPlugin.invokeMethod('oneAct');
  5. print(result);
  6. }
  7. Future<Null> _jumpToNativeWithValue() async {
  8. Map<String, String> map = { "flutter": "这是一条来自flutter的参数" };
  9. String result = await jumpPlugin.invokeMethod('twoAct', map);
  10. print(result);
  11. }

2、原生发送参数给Flutter

实现插件

  1. public class FlutterPluginCounter implements EventChannel.StreamHandler {
  2. public static String CHANNEL = "com.jzhu.counter/plugin";
  3. static EventChannel channel;
  4. private Activity activity;
  5. private FlutterPluginCounter(Activity activity) {
  6. this.activity = activity;
  7. }
  8. public static void registerWith(PluginRegistry.Registrar registrar) {
  9. channel = new EventChannel(registrar.messenger(), CHANNEL);
  10. FlutterPluginCounter instance = new FlutterPluginCounter(registrar.activity());
  11. channel.setStreamHandler(instance);
  12. }
  13. @Override
  14. public void onListen(Object o, final EventChannel.EventSink eventSink) {
  15. Observable.interval(1000, TimeUnit.MILLISECONDS).subscribe(new Observer<Long>() {
  16. @Override
  17. public void onSubscribe(Disposable d) {
  18. }
  19. @Override
  20. public void onNext(Long aLong) {
  21. eventSink.success(aLong.intValue());
  22. }
  23. @Override
  24. public void onError(Throwable e) {
  25. eventSink.error("计时器异常", "异常", e.getMessage());
  26. }
  27. @Override
  28. public void onComplete() {
  29. }
  30. });
  31. }
  32. @Override
  33. public void onCancel(Object o) {
  34. Log.i("FlutterPluginCounter", "FlutterPluginCounter:onCancel");
  35. }
  36. }

Flutter接收原生发送的参数

  1. static const counterPlugin = const EventChannel('com.jzhu.counter/plugin');
  2. StreamSubscription _subscription = null;
  3. var _count;
  4. @override
  5. void initState() {
  6. super.initState();
  7. //开启监听
  8. if(_subscription == null){
  9. _subscription = counterPlugin.receiveBroadcastStream().listen(_onEvent,onError: _onError);
  10. }
  11. }
  12. @override
  13. void dispose() {
  14. super.dispose();
  15. //取消监听
  16. if(_subscription != null){
  17. _subscription.cancel();
  18. }
  19. }
  20. void _onEvent(Object event) {
  21. setState(() {
  22. _count = event;
  23. print("ChannelPage: $event");
  24. });
  25. }
  26. void _onError(Object error) {
  27. setState(() {
  28. _count = "计时器异常";
  29. print(error);
  30. });
  31. }

其他

Debug模式原生跳转到Flutter界面会出现白屏,Release包就不会出现这种情况