Flutter如何和Native通信-Android视角,深度剖析原理

registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
batteryLevel = (intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100) /
intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
}

return batteryLevel;
}

这个函数需要能被Flutter app调用,此时就需要通过MethodChannel来建立这个通道了。 首先在MainActivityonCreate函数中加入以下代码来新建一个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来的调用
}
});
}
}

注意,每个MethodChannel需要有唯一的字符串作为标识,用以互相区分,这个名称建议使用package.module...这样的模式来命名。因为所有的MethodChannel都是保存在以通道名为Key的Map中。所以你要是设了两个名字一样的channel,只有后设置的那个会生效。

接下来我们来填充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();
}
}

onMethodCall有两个入参,MethodCall里包含要调用的方法名称和参数。Result是给Flutter的返回值。方法名是两端协商好的。通过if语句判断MethodCall.method来区分不同的方法,在我们的例子里面我们只会处理名为“getBatteryLevel”的调用。在调用本地方法获取到电量以后通过result.success(batteryLevel)调用把电量值返回给Flutter。 Native端的代码就完成了。是不是很简单?

MethodChannel-Flutter 端

接下来看Flutter端代码怎么写: 首先在 State中创建Flutter端的MethodChannel

import ‘dart:async’;

import ‘package:flutter/material.dart’;
import ‘package:flutter/services.dart’;

class _MyHomePageState extends State {
static const platform = const MethodChannel(‘samples.flutter.io/battery’);

// Get battery level.
}

channel的名称要和Native端的一致。 然后是通过MethodChannel调用的代码

String _batteryLevel = ‘Unknown battery level.’;

Future _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod(‘getBatteryLevel’);
batteryLevel = ‘Battery level at KaTeX parse error: Expected 'EOF', got '}' at position 14: result % .'; }̲ on PlatformExc…{e.message}’.";
}

setState(() {
_batteryLevel = batteryLevel;
});
}

final int result = await platform.invokeMethod('getBatteryLevel');这行代码就是通过通道来调用Native方法了。注意这里的await关键字。前面我们说过MethodChannel是异步的,所以这里必须要使用await关键字。 在上面Native代码中我们把获取到的电量通过result.success(batteryLevel);返回给Flutter。这里await表达式执行完成以后电量就直接赋值给result变量了。剩下的就是怎么展示的问题了,就不再细说了,具体可以去看代码。

需要注意的是,这里我们只介绍了从Flutter调用Native方法,其实通过MethodChannel,Native也能调用Flutter的方法,这是一个双向的通道

举个例子,我们想从Native端请求Flutter端的一个getName方法获取一个字符串。在Flutter端你需要给MethodChannel设置一个MethodCallHandler

_channel.setMethodCallHandler(platformCallHandler);

Future platformCallHandler(MethodCall call) async {
switch (call.method) {
case “getName”:
return “Hello from Flutter”;
break;
}
}

在Native端,只需要让对应的的channel调用invokeMethod就行了

channel.invokeMethod(“getName”, null, new MethodChannel.Result() {
@Override
public void success(Object o) {
// 这里就会输出 “Hello from Flutter”
Log.i(“debug”, o.toString());
}
@Override
public void error(String s, String s1, Object o) {
}
@Override
public void notImplemented() {
}
});

至此,MethodChannel的用法就介绍完了。可以发现,通过MethodChannelNative和Flutter方法互相调用还是蛮直接的。这里只是做了个大概的介绍,具体细节和一些复杂用法还有待大家的探索。

MethodChannel提供了方法调用的通道,那如果Native有数据流需要传送给Flutter该怎么办呢?这时候就要用到EventChannel了。

EventChannel

EventChannel的使用我们也以官方获取电池电量的demo为例,手机的电池状态是不停变化的。我们要把这样的电池状态变化由Native及时通过EventChannel来告诉Flutter。这种情况用之前讲的MethodChannel办法是不行的,这意味着Flutter需要用轮询的方式不停调用getBatteryLevel来获取当前电量,显然是不正确的做法。而用EventChannel的方式,则是将当前电池状态"推送"给Flutter.

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

总结

找工作是个很辛苦的事情,而且一般周期都比较长,有时候既看个人技术,也看运气。第一次找工作,最后的结果虽然不尽如人意,不过收获远比offer大。接下来就是针对自己的不足,好好努力了。

最后为了节约大家的时间,我把我学习所用的资料和面试遇到的问题和答案都整理成了PDF文档,都可以分享给有需要的朋友,如有需要私信我【资料】或者**【点这里】免费领取**

《Android面试复习资料汇总》

喜欢文章的话请关注、点赞、转发 谢谢!

要的朋友,如有需要私信我【资料】或者**【点这里】免费领取**

《Android面试复习资料汇总》

喜欢文章的话请关注、点赞、转发 谢谢!

  • 24
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值