美文网首页
Flutter与原生Android之间的通信

Flutter与原生Android之间的通信

作者: DASH_1024 | 来源:发表于2019-06-02 19:53 被阅读0次

    我们都知道Flutter开发的app是可以同时在iOS和Android系统上运行的。显然Flutter需要有和Native通信的能力,Flutter与原生系统主要有三种通信形式:MethodChannel和EventChannel及BasicMessageChannel。

    简单介绍

    • BasicMessageChannel:用于传递字符串和半结构化的信息,持续通信,收到消息后可以回复此次消息,如:Native将遍历到的文件信息陆续传递到Dart,在比如:Flutter将从服务端陆陆续获取到信息交个Native加工,Native处理完返回等;
    • MethodChannel:用于传递方法调用(method invocation)一次性通信:如Flutter调用Native拍照;
    • EventChannel: 用于数据流(event streams)的通信,持续通信,收到消息后无法回复此次消息,通常用于Native向Dart的通信,如:手机电量变化,网络连接变化,陀螺仪,传感器等;

    这三种类型的类型的Channel都是全双工通信,即A <=> B,Dart可以主动发送消息给platform端,并且platform接收到消息后可以做出回应,同样,platform端可以主动发送消息给Dart端,dart端接收数后返回给platform端。

    应用场景

    • 初始化Flutter时Native向Dart传递数据;
    • Native发送数据给Dart;
    • Dart发送数据给Native;
    • Dart发送数据给Native,然后Native回传数据给Dart;

    原理

    原理.png

    应用

    这里以获取电池电量为例,先在MainActivity中增加一个获取电量的函数:

    private int getBatteryLevel() {
      int batteryLevel = -1;
      if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
        BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE);
        batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
      } else {
        Intent intent = new ContextWrapper(getApplicationContext()).
            registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
        batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
            intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
      }
    
      return batteryLevel;
    }
    

    在MainActivity中创建MethodChannel:

    public class MainActivity extends FlutterActivity {
        //channel的名称,由于app中可能会有多个channel,这个名称需要在app内是唯一的。
        private static final String CHANNEL = "samples.flutter.io/battery";
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
            GeneratedPluginRegistrant.registerWith(this);
            
            // 直接 new MethodChannel,然后设置一个Callback来处理Flutter端调用
            new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
                    new MethodCallHandler() {
                        @Override
                        public void onMethodCall(MethodCall call, Result result) {
                            // 在这个回调里处理从Flutter来的调用
                        }
                    });
        }
    }
    

    接下来我们来填充onMethodCall:

    @Override
    public void onMethodCall(MethodCall call, Result result) {
        if (call.method.equals("getBatteryLevel")) {
            int batteryLevel = getBatteryLevel();
    
            if (batteryLevel != -1) {
                result.success(batteryLevel);
            } else {
                result.error("UNAVAILABLE", "Battery level not available.", null);
            }
        } else {
            result.notImplemented();
        }
    }  
    

    Flutter 端

    import 'dart:async';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    ...
    class _MyHomePageState extends State<MyHomePage> {
      static const platform = const MethodChannel('samples.flutter.io/battery');
    
      // Get battery level.
    }
    

    通过MethodChannel调用的代码:

      String _batteryLevel = 'Unknown battery level.';
    
      Future<Null> _getBatteryLevel() async {
        String batteryLevel;
        try {
          final int result = await platform.invokeMethod('getBatteryLevel');
          batteryLevel = 'Battery level at $result % .';
        } on PlatformException catch (e) {
          batteryLevel = "Failed to get battery level: '${e.message}'.";
        }
    
        setState(() {
          _batteryLevel = batteryLevel;
        });
      }
    

    这样我们就能实现与Flutter端与Android与原生端的简单通信了。Flutter作为一种跨平台解决方案,经常会作为一个模块嵌入到原生Android与iOS应用中,Flutter与Android原生端的通信必不可少。本文主要讲解了下通过MethodChannel实现通信的简单步骤及原理,需要在实际开发中经常使用。

    相关文章

      网友评论

          本文标题:Flutter与原生Android之间的通信

          本文链接:https://www.haomeiwen.com/subject/pqqfxctx.html