Flutter和Android
【前言】
1:先简单的介绍下Flutter,它是一款跨平台应用SDK,高性能跨平台实现方案(暂时讨论iOS和Android),
它不同于RN,少了像RN的JS中间桥接层,所以它的性能相比RN有了很好的提升。
2:Flutter从谷歌推出以来,我就开始关注,到现在3.0以上的版本,SDK也逐步稳定,目前我们的网约车项目也开始集成Flutter组件,并且效果不错。
3:Flutter弊端也是很明显,目前支持移动端的第三方框架可选性还不多。
对于iOS和Android来说,使用Flutter开发一套完整的APP,还是需要了解两端的开发知识,所以使用Flutter,还得并行学习提高跨平台技能。
4:对于Flutter跨平台实现方案,目前我整理了2套可行方案:
(1):全部使用Flutter框架,包括核心功能部分,缺点未知风险可能比较多,不做优先选择。
(2):核心功能使用原生,其他功能使用原生与Flutter交互,优点是风险最小并可控,也是最好选择方案。当然对于跨平台开发者的跨平台技能要求较高。
【跨平台选择】
1:我们项目中目前使用原生与Flutter交互,实现的跨平台方案,所以本文主要介绍‘原生与Flutter’集成和交互功能(暂时讨论iOS和Android)。
2:之前公司有过一次Flutter的技术分享会,相关资料和项目实践资料都有整理过,因为开发需求一直比较多,所以拖到今天才在博客上分享和大家一起研究。
3:Flutter环境的配置和安装本文就不讲了,最全面的教程可以去官网找。
【Android原生集成Flutter】
注意:Android原生集成Flutter方案已经又更新,所以原来的操作已经行不通了,下面的是新版方案。
使用 .gradle 把 Flutter 模块集成到工程中,步骤如下:
(1):生成的Flutter工程(或者是git上下载的Flutter工程)放在与Android原工程同级目录, 如下:(红色部分为flutter项目名称)
---指定目录,创建Flutter工程(生成指令:flutter create -t module flutter_module_test),放在与Android原工程同级目录:
(2):使用gradle,把 Flutter 工程集成到Android项目环境中
打开 AndroidApp/settings.gradle,增加如下配置:
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
"flutter_module_test/.android/include_flutter.groovy"
))
然后Sync一下,,Flutter项目已经集成进来了。
(3):然后,在项目的app目录下,build.gradle文件中,添加如下dependency:
implementation project(':flutter')
然后Sync一下,集成 Flutter框架。
(4):运行报错处理 - 1
如果遇到集成Flutter项目报错,确认下 Flutter 项目下 android 文件中 include_flutter.groovy 文件是否存在,如图:
,核心文件不能少。
缺少解决方案:重新创建flutter项目或者从别的地方拷贝一个文件放到对应目录,然后Android执行Sync一下。
(5):运行报错处理 - 2
整体配置就这么简单,但是运行的时候的时候,项目挂了,出现了以下错误
-
错误: 程序包android.support.annotation不存在
-
错误: 找不到符号
-
符号: 类 Fragment
-
错误: 找不到符号
-
符号: 类 NonNull
-
位置: 类 FlutterFragment
-
错误: 方法不会覆盖或实现超类型的方法
-
错误: 找不到符号
-
符号: 方法 getArguments()
-
位置: 类 FlutterFragment
-
错误: 方法不会覆盖或实现超类型的方法
-
错误: 方法不会覆盖或实现超类型的方法
查看编译后的源码,确实 flutter_module 中一些依赖包不存在
google 一番之后发现是 Android 包管理机制的问题,如果我们在安装 Android Studio
的时候勾选了 Androidx
,会默认使用 androidx
管理, 如图
对于这个,解决方案有:
1:下载Android Studio
重新安装,这种比较麻烦
2:全局修改配置,借助 Android Studio
工具实现代码 迁移,但是这些步骤还是不能解决我的问题,我的flutter_module 包依旧有一些旧的引用代码形式,
仔细分析,我的 flutter_module 是通过 flutter create -t module
这种方式实现的,可能是这种命令生成的代码是旧的包管理机制,
猜想有没有生成 androidx 机制的呢,Google 之后,发现真的有
-
flutter create --androidx -t module flutter_module 重新生成项目,移代码
(6):运行报错处理 - 3
Invoke-customs are only supported starting with Android O (--min-api 26)
解决方案:添加版本控制
添加目录:app -> build.grade -> android{ 此处添加 }
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
(7):完成上面步骤,Android执行Sync指令,flutter项目集成到Android原生项目中的就完成了。
每次fluter项目中代码有改动(我使用的VSCode开发fluter),Android只要通过终端Sync指令,就能同步fluter的最新代码到IDE中。
【Android 跳转指定 Flutter 页面和交互】
---实现方案:通过创建Activity,通过创建添加 FlutterFragment
,FlutterFragment
由channel发送信号判断类型实现:
(1):Android 跳转指定 Flutter 页面实现
使用FlutterFragment
新版本的FlutterSDK不再支持已经没有Flutter类,不再支持诸如Flutter.createView()、Flutter.createFragment()等用法,
通过阅读其源码我们可以找到FlutterFragment的新用法,代码如下:
public class MyFlutterActivity extends FragmentActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.flutter_layout); // 处理打开对应 Flutter界面 FlutterFragment fragment=FlutterFragment.withNewEngine().initialRoute("page_home").build(); getSupportFragmentManager().beginTransaction().add(R.id.flutter_container, fragment).commit(); } }
注:Activity:需要继承 FragmentActivity,page_home:为跳转Flutter页面类型参数,
R.id.flutter_container:为
fragment 容器。
(2):flutter判断来自Android的跳转目标实现(Dart代码演示)
void main(){ //flutter主入口
(3):flutter主动交互Android(Dart代码演示)
class HomePage extends StatefulWidget {
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
static const EventChannel eventChannel = const EventChannel('com.pages.your/native_post'); //注册一个信号通道
void _onEvent(Object event) { // Android 交互回调,返回值FlutterError为nill,执行此方法。FlutterError是什么数据,情况下面。
// Android 交互成功
}
void _onError(Object error) { // Android 交互回调,返回值FlutterError有值,执行此方法
// Android 交互失败
}
}
(4):Android 接送处理来自flutter的交互
【Android and Flutter结语】
人生就像美丽的花朵
1:谷歌推出Flutter时间大概一年左右,版本也一直在更新和推进,所以与原生的集成和交互也一直在更新,这就需要我们时刻保持学习状态,动态更新技能。
2:Android 和 Flutter的交互方式,并非就上面我分享的一种,也有其他的方式,相比而言,我的方案还是比较简洁和实用。
3:作为一个移动端专业开发者,我们应该保持对新技术的热情,跨平台方案离我们已经不再遥远,相信未来会普及和更加完善。
4:如果技术上有不同看法或者新的技术,欢迎联系一起讨论,本人QQ: 497609288。