Flutter与Android原生交互
记录一下小白的学习之路,图片都是走过的坑
文末附demo地址
文章目录
- 创建project
- Android端(native)
- Flutter端
- Android调用flutter
创建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);}@Overridepublic void onMethodCall(MethodCall call, MethodChannel.Result result) {//通过MethodCall可以获取参数和方法名,然后再寻找对应的平台业务//接收来自flutter的指令,trun2Second跳转到原生的第二个页面if (call.method.equals("trun2Second")) {//跳转到指定ActivityIntent 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.@overrideWidget 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');}}@overridevoid initState() {super.initState();}@overrideWidget 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() {@Overridepublic void success(Object o) {// 这里就会输出"Hello from Flutter"Log.i(">>>>>>>>>>debug", o.toString());}@Overridepublic void error(String s, String s1, Object o) {}@Overridepublic 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;}}@overrideinitState() {super.initState();// Platforms -> Dart_channel.setMethodCallHandler(_platformCallHandler);}
demo下载:https://github.com/gaoscxy/flutter_demo
Flutter与Android原生交互相关推荐
- flutter与android原生通信
1.原因 刚接触flutter的时候,以为flutter是一个全新开发app的语言,独立于Android原生之外的操作,入坑之后发现不是的.因为Flutter不能完成所有Native的功能,比如不同平 ...
- flutter调用android 原生TextView
https://blog.csdn.net/zl18603543572/article/details/95983215 本文链接:https://blog.csdn.net/zl1860354357 ...
- Flutter 和 Android 原生的区别
什么是Flutter ? Flutter 是一个软件开发工具包 (SDK),用于构建适用于 iOS 和 Android 的现代移动应用程序,可帮助开发人员和设计人员.Flutter 被归类为" ...
- RN与Android原生交互
前言:最开始做RN开发的时候,没有和原生打交道,结果居然把项目做出来,后来有人问我,RN页面可以跳转到Activity页面吗?我蒙了,我想了一下为什么还要调到原生页面呢?那样就不兼容andoid和io ...
- rn+android+sdk,RN与Android原生交互
场景:在RN界面中需要调用原生的拍照和选择相册功能,将拍照或者选择的照片的路径回传给RN 步骤如下: 1.RN的界面跳转到原生Activity,并接收从原生回传的数据 import React, { ...
- RN 与android原生交互
缘由 有时候App需要访问平台api,但在RN中没有相应的模块,或者需要你复用一些原生代码,这就需要进一步开发RN原生模块.一般用React Native开发App时会用到一些原生模块,比如:在做社会 ...
- android studio放置在函数上面看_像写Flutter一样开发Android原生应用
要问到Flutter和Android原生App,在开发时有何区别,编程方式是绕不开的话题.Flutter采用声明式编程,Android原生开发则采用命令式编程. 声明式编程 VS. 命令式编程 我们首 ...
- Flutter中嵌入Android 原生TextView
更多文章请查看 flutter从入门 到精通 本篇文章 中写到的是 flutter 调用了Android 原生的 TextView 案例 添加原生组件的流程基本上可以描述为: 1 android 端实 ...
- 像写Flutter一样开发Android原生应用
要问到Flutter和Android原生App,在开发是有何区别,编程方式是绕不开的话题.Flutter采用声明式编程,Android原生开发则采用命令式编程. 声明式编程 VS. 命令式编程 我们首 ...
最新文章
- 贪心:jump 游戏(获取最少跳跃的次数以及跳跃路径)
- 有AI学会控制核聚变反应堆了,来自DeepMind,登上今日Nature
- hdu 5751 Eades
- Java 三大框架集成项目结构
- 运城学院数学与计算机系,运城学院数学与信息技术学院.doc
- oracle USER 与 Schema 的关系与区别
- [Python]程序结构与控制流
- java初始化变量n_java中预构造函数初始化变量的属性
- N天学习一个linux命令之rsync
- Linux 块与文件大小
- 指定 年-月-日 将其封装tree树状结构
- 卸载win10预装软件和小娜
- C语言递归方法求解背包问题
- 时间的质量:为什么时光飞逝
- IDEA 启动本地 Flink Web UI
- html前端使用高德地图入门教程,并在地图上标记位置
- 【测试开发】一个5年测试开发的成长经验,大学毕业就开启他的职业生涯......
- Python 使用SMTP协议发送邮件
- 2.2 复习过去式和过去完成时 现在完成时
- 织梦网站地图生成插件下载