Flutter与原生Android之间的通信

2019-06-02  本文已影响0人  DASH_1024

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

简单介绍

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

应用场景

原理

原理.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实现通信的简单步骤及原理,需要在实际开发中经常使用。

上一篇下一篇

猜你喜欢

热点阅读