方案挑选:
目前主要有两种集成方式:
1、源码集成:就是谷歌官方提供的方案( https://github.com/flutter/flutter/wiki/Add-Flutter-to-existing-apps )
2、 产物集成: Flutter项目单独开发,开发完成后发布成安卓以aar包,iOS的framework形式,原生项目依赖flutter输出的制品就可以了,具体可以看闲鱼的文章,他们就是这么干的,借用网上的一张图
两种方案各有优劣,鉴于我们项目参与人数众多,如果采用源码集成的方式,所有人都得配相应的环境和了解相关的知识,显然成本较高,所有我们选择了第二种方式,专门几个人去做flutter项目然后以AAR包的方式集成到项目中来
这篇文章里我两种都尝试一下,当然我是安卓这边的尝试
直接从AS的图形界面导入已经新建的flutter module尝试失败
这样导入flutter module失败
正确打开方式:
1、使用Android Studio来创建Flutter Module(放在原生的同级目录)
1、 依次点击左上角的File --> New --> New Flutter Project
2、然后选择Flutter Module。
如图:
2、在项目的根目录settings.gradle文件中配置:
include ':app'
include ':flutter_module'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'主项目名称/flutter_module名称/.android/include_flutter.groovy'))
关于这个配置,new File(settingsDir.parentFile,‘my_flutter/.android/include_flutter.groovy’ ) 解读下这句话的意思就是指定 include_flutter.groovy 的所在位置。这里的意思是在 settings 文件所在目录(settingsDir)的父目录有个文件(settingsDir.parentFile)my_flutter/.android/include_flutter.groovy。看下下面的文件放置位置图就清楚了:
所以官网在跟项目同级创建 flutter module 是没问题的。但是我们现在改了,应该怎样设置呢?
Tips:注意相对路径的使用,重点是找到 include_flutter.groovy
解法一:
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir,
'sub/my_flutter/.android/include_flutter.groovy'
))
在 settings 所在目录有 sub/my_flutter/.android/include_flutter.groovy 文件
解法二:
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'MyApp/sub/my_flutter/.android/include_flutter.groovy'
))
在 settings 所在目录的父目录有 MyApp/sub/my_flutter/.android/include_flutter.groovy 文件
这里我用了第二种方案
参考:https://juejin.im/post/5c67d4326fb9a04a0b22b627
3、在app下的gradle文件中添加
implementation project(':flutter')
完成这三步就顺利完成在原生项目中集成flutter module了
安卓原生界面跳转到flutter界面有两种方式,一种是使用flutterView,另一种是使用 FlutterFragment ,这里我选择了前者
先新建一个activity,FlutterViewActivty(随意命名),在oncreate方法中加入以下代码
private fun initView() {
val flutterView: View = Flutter.createView(this, lifecycle, "flutter Route1")
val layoutParams = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
addContentView(flutterView, layoutParams)
}
Flutter.createView()
方法返回的是一个FlutterView,它继承自View,我们可以把它当做一个普通的View,调用addContentView()
方法将这个View添加到Activity的contentView中。我们注意到Flutter.createView()
方法的第三个参数传入了"flutter Route1"字符串,表示路由名称,它确定了Flutter中要显示的Widget,接下来需要在之前创建好的Flutter Module中编写逻辑了,修改main.dart文件中的代码
``
Widget _widgetForRoute(String route) {
switch (route) {
case "flutter Route1":
return Scaffold(
appBar: AppBar(
title: Text("test native"),
),
body: Center(
child: Text('flutter 页面,route=$route'),
),
);
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
在runApp()方法中通过window.defaultRouteName可以获取到我们在Flutter.createView()方法中传入的路由名称,即"flutter Route1",之后编写了一个_widgetForRoute()方法,根据传入的route字符串显示相应的Widget。
最后在Mainacivity中加入跳转事件
switch (v.getId()) {
case R.id.btn_flutter:
Intent intent = new Intent(MainActivity.this, FlutterViewActivity.class);
startActivity(intent);
break;
}
大功告成!!
但是发现原生的标题栏还在,在style中加入透明标题栏样式
<style name="FlutterTheme" parent="AppTheme.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
顺利完成,如图,点击跳转的时候会有黑屏一下的现象,不过没事,这是debug情况才会有的,debug有一些调试的预加载,打了release包之后就没有这个现象了
1、Android 原工程需要使用 java 8 编译
在 工程的 build.gradle 里面,android {} 下修改
android {
//...
compileOptions {
sourceCompatibility 1.8
targetCompatibility 1.8
}
}
2、生成 aar 文件
通过集成 arr 的方式需要先生成 Flutter Module 的 arr,在 Flutter Module 的根目录下运行以下命令
flutter build aar
3、使用 aar
主工程的 build.gradle repositories 闭包 里面加入
flatDir {
dirs 'libs' // aar目录
}
然后把AAR包复制到libs目录下面, app 的 build.gradle 里面添加依赖
implementation (name:'flutter-release-old',ext:'aar')
跳转的代码和方式一一样不用动,编译运行之后成功
参考:
https://www.jianshu.com/p/5ef007d83b34
https://www.jianshu.com/p/7b6522e3e8f1