记录一下小白的学习之路,图片都是走过的坑
文末附demo地址
创建project
首先创建Flutter Project,Android Studio集成flutter开发环境自行百度,语言我选择了Kotlin,不熟悉的可以选择Java,不要忘记勾选 Create project offline,否则会让你等到地老天荒
创建成功后的界面是这个样子
Flutter 定义了三种不同的 Channel
MethodChanel:用于传递方法调用(method invocation)
EventChannel:用于事件流的发送(event streams)
MessageChannel:用于传递字符串和半结构化的消息
*这里是抄的,嘿嘿嘿*
此间只说下MethodChanel
Android端(native)
为了方便开发,我们用Android Studio打开android目录
打开后的目录如下,其中flutterplugin、OneActivity、SeconActivity是我后添加的,其他是自动生成
首先,创建MethodChannel,在FlutterPlugin定义final类型的CHANNEL,通常为“包名/标识”,这里一定要和跟flutter中使用相同的注册字符串,否则无法完成互调。registerWith方法用于注册渠道。然后,设置MethodCallHander,methodCall中传递来自flutter的参数,通过result返回给flutter结果。本案例做了4个操作,详见注释
public class FlutterPlugin implements MethodChannel.MethodCallHandler {
public static final String CHANNEL = "com.example.flutter_demo2/jump_plugin";
static MethodChannel channel;
private Activity activity;
private FlutterPlugin(Activity activity) {
this.activity = activity;
}
public static void registerWith(FlutterEngine flutterEngine, FlutterActivity activity) {
channel = new MethodChannel(flutterEngine.getDartExecutor(), CHANNEL);
FlutterPlugin instance = new FlutterPlugin(activity);
//setMethodCallHandler在此通道上接收方法调用的回调
channel.setMethodCallHandler(instance);
}
@Override
public void onMethodCall(MethodCall call, MethodChannel.Result result) {
//通过MethodCall可以获取参数和方法名,然后再寻找对应的平台业务
//接收来自flutter的指令,trun2Second跳转到原生的第二个页面
if (call.method.equals("trun2Second")) {
//跳转到指定Activity
Intent intent = new Intent(activity, SecondActivity.class);
activity.startActivity(intent);
//返回给flutter的参数
result.success("success");
}
//接收来自flutter的指令,获取flutter传递过来的参数
else if (call.method.equals("mapData")) {
//解析参数
String value = call.argument("flutter");
Log.v("debug", value);
Toast.makeText(activity, value, Toast.LENGTH_SHORT).show();
//返回给flutter的参数
result.success("success");
}
//接收来自flutter的指令,flutter调用原生方法传多个参数并取得返回值
else if (call.method.equals("getNativeResult")) {
//解析参数
String value1 = call.argument("key1");
String value2 = call.argument("key2");
Log.v("debug", value1 + value2);
//返回给flutter的参数
result.success("success");
}else if(call.method.equals("goBack")){
//flutter返回到上一页原生界面
activity.finish();
}
else {
result.notImplemented();
}
}
再来看MainActivity,继承FlutterActivity
覆写configureFlutterEngine方法,给此类注册组件
class MainActivity: FlutterActivity() {
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
GeneratedPluginRegistrant.registerWith(flutterEngine)
//给当前页面注册组件
FlutterPlugin.registerWith(flutterEngine, this)
}
}
注意:
application需要增加主题,否则报错
Android的启动页换成OneActivity,否则启动会直接跳转到flutter页
从OneActivity 跳转到flutter页:
class OneActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_one)
}
//点击按钮跳转
fun turn2flutter(view: android.view.View) {
val intent = Intent()
intent.setClass(this,MainActivity::class.java)
startActivity(intent)
}
}
Flutter端
创建MethodChannel,并注册channel名,这里再提醒一下,要与native里“包名/标识”的一致
通过invokeMethod发起异步调用,invokeMethod接受两个参数:
method:调用的native方法名
arguments:nativie方法参数,有多个参数时需要以map形式指定
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
//获取插件与原生Native的交互通道
static const platForm = const MethodChannel('com.example.flutter_demo2/jump_plugin');
//具体要做的功能
void _goToNativeActivity() async {
String result = await platForm.invokeMethod('trun2Second');
print(result);
}
// 具体要做的功能
void _sendDataToNative() async {
Map<String, String> map = {"flutter": "我是flutter 传递过来的"};
String result = await platForm.invokeMethod('mapData', map);
print(result);
}
String nativeBackString = 'Not return';
void _invokeNativeGetResult() async {
String backString;
try {
// 调用原生方法并传参,以及等待原生返回结果数据
var result = await platForm.invokeMethod('getNativeResult', {'key1':'flutter参数1','key2':'flutter参数2'});
backString = 'Native return $result';
} on PlatformException catch (e) {
backString = "Failed to get native return: '${e.message}'.";
}
setState(() {
nativeBackString = backString;
});
}
void _goBackToNative(){
if (Navigator.canPop(context)) { // 返回上一页
Navigator.of(context).pop();
} else {
platForm.invokeMethod('goBack');
}
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
// flutter 注册原生监听方法
return new Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
// Center is a layout widget. It takes a single child and positions it
// in the middle of the parent.
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
child: Text('跳转到第二个原生页面'),
onPressed: () {
_goToNativeActivity();
},
),
RaisedButton(
child: Text('flutter向原生传递数据'),
onPressed: () {
_sendDataToNative();
},
),
RaisedButton(
child: Text('调用原生方法并传参'+'\n原生传递过来的值 $nativeBackString'),
onPressed: () {
_invokeNativeGetResult();
},
),
RaisedButton(
child: Text('返回第一个原生界面'),
onPressed: () {
_goBackToNative();
},
),
],
),
),
);
}
}
Android调用flutter
Android调用flutter类似,注意调用要在UI线程进行
//android调用flutter方法 并获取结果
channel.invokeMethod("flutterMedia", "from android", 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() {
}
});
flutter里实现MethodCallHandler的注册:
Future<dynamic> _platformCallHandler(MethodCall call) async {
switch (call.method) {
case 'flutterMedia':
print('call flutterMedia: arguments = ${call.arguments}');
return Future.value('Hello from Flutter!');
//return Future.error('error message!!');
default:
print('Unknowm method ${call.method}');
throw MissingPluginException();
break;
}
}
@override
initState() {
super.initState();
// Platforms -> Dart
_channel.setMethodCallHandler(_platformCallHandler);
}
demo下载:https://github.com/gaoscxy/flutter_demo