这里的 await 是因为这个操作是异步的。同时 _getBatteryLevel 也要改为对应的异步方法,因此最终方法代码如下:
Future<void> _getBatteryLevel() async { String batteryLevel; try { final int result = await methodChannel.invokeMethod('getBatteryLevel'); batteryLevel = 'Battery level: $result%.'; } on PlatformException { batteryLevel = 'Failed to get battery level.'; } setState(() { _batteryLevel = batteryLevel; }); }可以看到通过异步方法获取到电量之后通过 setState 方法更新界面。
5. 原生定义 MethodChannel private static final String BATTERY_CHANNEL = "samples.flutter.io/battery";注意需要跟 Flutter 的一一对应。
6. 原生调用创建 MethodChannel 并通过 MethodCallHandler 接收 Flutter 的方法调用 new MethodChannel((FlutterView)flutterView, BATTERY_CHANNEL).setMethodCallHandler( new MethodChannel.MethodCallHandler() { @Override public void onMethodCall(MethodCall call, MethodChannel.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(); } } } );可以看到我们是通过 call.method 来区分 Flutter 的不同方法调用。
这里 result.success 返回成功回调。 result.error 返回错误回调。result.notImplemented 表明没有对应实现。
最后我们实现原生 getBatteryLevel 方法即可。
如下:
private int getBatteryLevel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { BatteryManager batteryManager = (BatteryManager) getSystemService(BATTERY_SERVICE); return batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY); } else { Intent intent = new ContextWrapper(getApplicationContext()). registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); return (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1); } }运行点击按钮,效果如下:
到此我们 Flutter 调用原生并获取返回值的方法就介绍完了。
这里我们总结如下:
Flutter 准备工作:
定义 MethodChannel
通过异步方法调用 methodChannel 的 invokeMethod 指定这个 methodChannel 具体要调用的方法名
原生准备工作:
定义 CHANNEL(与 Flutter 对应)
创建 MethodChannel 并通过 setMethodCallHandler 方法来区分 Flutter 的不同调用方法名和返回对应的回调
源码位置:
https://github.com/nesger/FlutterSample/tree/feature/method_channel
https://flutter.dev/docs/development/platform-integration/platform-channels
https://github.com/flutter/flutter/tree/master/examples/platform_channel
更多阅读:
Flutter 即学即用系列博客
Flutter 即学即用系列博客——01 环境搭建
Flutter 即学即用系列博客——02 一个纯 Flutter Demo 说明
Flutter 即学即用系列博客——03 在旧有项目引入 Flutter
Flutter 即学即用系列博客——04 Flutter UI 初窥
Flutter 即学即用系列博客——05 StatelessWidget vs StatefulWidget
Flutter 即学即用系列博客——06 超实用 Widget 集锦
Flutter 即学即用系列博客——07 RenderFlex overflowed 引发的思考
Flutter & dart
dart 如何优雅的避空
Flutter map 妙用及 .. 使用