使用MethodChannel方式通信
在建 好工程以后,发现android的工程as识别不了.问题就来了,我要写kotlin或java代码没有提示.
打开,project structure->modules,右侧应该可以看到项目的目录了.
看图,将java目录选为source,res选为resouces.
然后选择上面的dependenciestab,在底部会看到+号:
在弹出的窗口中选择new library.进入jar文件选择.flutter的安装目录下.
- flutter/bin/cache/artifacts/engine/android-arm/flutter.jar
这里有好多个jar,我随便选择了一个,只是支持的cpu架构不同.选完以后就可以高亮提示了.
开始通信:
在MainActivity extends FlutterActivity中.
private MethodChannel mMethodChannel;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GeneratedPluginRegistrant.registerWith(this);
flutterView = getFlutterView();
methodChannelFunc();
}
private void methodChannelFunc() {
//flutter_and_native_mc 这个名字就是通信标识.flutter端要一致.
mMethodChannel = new MethodChannel(flutterView, "flutter_and_native_mc");
mMethodChannel.setMethodCallHandler(
new MethodChannel.MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
String method = call.method;
if (method.equals("method1")) {
Toast.makeText(mContext, "flutter 调用到了 android method1", Toast.LENGTH_SHORT).show();
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "android 调用 flutter method1方法");
mMethodChannel.invokeMethod("method1", resultMap,
new MethodChannel.Result() {
@Override
public void success(Object o) {
Log.d("tag", "msg:" + o);
}
@Override
public void error(String s, String s1, Object o) {
Log.d("tag", "error:" + s + " s1:" + s1 + " o:" + o);
}
@Override
public void notImplemented() {
}
});
} else if (method.equals("method2")) {
String args = call.argument("test_key");
if (!TextUtils.isEmpty(args)) {
Log.d("tag", "args:" + args);
}
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("message", "native 接收到了参数:" + args);
resultMap.put("code", 200);
result.success(resultMap);
//这里通过result.success与下面的不一样.
mMethodChannel.invokeMethod("method2", resultMap);
} else {
result.notImplemented();
}
}
}
);
}
native部分就完成了.比较简单的.
flutter部分
建一个StatefulWidget.
state里:
static const methodChannel = const MethodChannel('flutter_and_native_mc');
static Future<dynamic> invokNative(String method, {Map args}) async {
if (args == null) {
return await methodChannel.invokeMethod(method);
} else {
return await methodChannel.invokeMethod(method, args);
}
}
Future<dynamic> callHandler(MethodCall call) async {
String method = call.method;
switch (call.method) {
case "method1":
Map arguments = call.arguments;
String message = arguments["message"];
setState(() {
str += "method1:$method, message:$message \n";
print(str);
});
break;
case "method2":
Map arguments = call.arguments;
String message = arguments["message"];
setState(() {
str += "method2:$method, message:$message \n";
print(str);
});
break;
}
}
//注册:
void registMessageListener() {
methodChannel.setMethodCallHandler(callHandler);
}
@override
void initState() {
super.initState();
registMessageListener();
}
把widget用ListView组合起来就行了:
@override
Widget build(BuildContext context) {
return Scaffold(
body: buildWidget(context),
);
}
buildWidget(BuildContext context) {
return ListView(
children: <Widget>[
Column(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Padding(
padding: EdgeInsets.all(4),
child: FlatButton(
color: Colors.grey,
onPressed: () {
Map args = Map();
args["test_key"] = "test_value";
invokNative("method2", args: args)
..then((result) {
String message = result["message"];
setState(() {
str += "native 中的回调 message $message \n";
});
});
},
child: Text(
"发送消息带参数的",
style: TextStyle(color: Colors.white),
)),
),
Padding(
padding: EdgeInsets.all(10),
child: Text(
"接收到的消息 $str",
style: TextStyle(color: Colors.blue, fontSize: 14),
),
),
],
)
],
);
这时,会接收到两个值.一个是这里的then,有返回,这个返回值是由native的result.success(resultMap);部分得到的
另一个是callHandler里面得到的,这部分是native的mMethodChannel.invokeMethod("method2", resultMap);发出的.
需要注意不同的反馈方式.