近期一直在搞Flutter&Android,主要技能iOS都快丢了
交互方法在跟随Flutter的版本改变而改变,我Flutter的版本是1.17.5
,看之前的交互方法都过时不能用了,研究了哈API整个能用的,废话不多直接开整(只讲实现不讲原理,感觉跟iOS的notification差不多)
准备工作
在Flutter中加个MethodChannel
并取个标识符,我这里就取个xxx吧,Android端等下会用到
static const _channel = const MethodChannel('xxx')
在Flutter
中调用Android
方法
例如
Flutter调用Android的phoneInfo去获取手机信息,Android返回参数
Flutter传参调用Android的disableDropDown,Android获取参数执行操作
Flutter端
String result = await _channel.invokeMethod('phoneInfo');//result用于接收传递回来的参数
if(result != null){
setState(() {
info = result;
});
}
_channel.invokeMethod('disableDropDown',{"disableDropDown":true});//传参参数名我就取disableDropDown了,自己根据业务取
Android端
我创建Flutter项目MainActivity默认是Kotlin的,所以这里就已Kotlin版本的MainActivity为例,在MainActivity中重写configureFlutterEngine方法
值得注意:不管执行结果如何都要执行result.success或者result.error,否则Flutter端可能会一直等待响应
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
//这里为Android调用Flutter做准备
FlutterEngineCache.getInstance().put("myEngine",flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger,"xxx").setMethodCallHandler { call, result ->
when(call.method){
"phoneInfo" -> {
val info = toolManager.deviceInfo
//带参数返回
result.success(info)
}
"disableDropDown" -> {
if (call.hasArgument("disableDropDown")){
val disableDropDown: Boolean? = call.argument("disableDropDown")
if (disableDropDown != null) {
if (disableDropDown){
toolManager.prohibitDropDown()
}else{
toolManager.enableDropDown()
}
}
//不带参数返回
result.success(null)
}else{
//返回错误消息
result.error("","缺少参数","")
}
}
else -> {
result.notImplemented()//没有该方法
}
}
}
}
就这么简单,接下来是Android调用Flutter,更简单,只是需要注意线程问题,UI相关就放主线程执行,耗时操作放子线程然后event更新即可
在Android
中调用Flutter
方法
例如
Android端调用location方法并传参给Flutter,当然不传参数不加参数,也不取参数就行了,这里就写个带参数的,要学会举一反三
Flutter端
就刚刚那个_channel可以继续用,我用的StatefulWidget
,在initState方法中给它加个Handler接收消息
_channel.setMethodCallHandler((call) async {
if(call.method == "location"){
String location = await call.arguments['location'];
if(location != null){
setState(() {
info = location;
});
}
}
});
Android端
MethodChannel methodChannel = new MethodChannel(FlutterEngineCache.getInstance().get("myEngine").getDartExecutor().getBinaryMessenger(), "xxx");//之前准备的在这用上了
Map<String, String> map = new HashMap<>();
map.put("location","我是参数值");
((MainActivity) mContext).runOnUiThread(new Runnable() {
@Override
public void run() {
methodChannel.invokeMethod(method, map);
}
});
网友评论