Flutter安装
git clone下来,然后配置一下path即可
集成步骤
(一)在目标目录的同级目录执行如下命令,创建
代码语言:txt复制$ flutter create -t module <module_name>
(二)进入到你创建的flutter目录下,执行:
代码语言:txt复制$ cd .android
$ ./gradlew flutter:assembleDebug
可能出现的错误: 这时候可能卡在
resoving dependencies gradle-3.1.4.pom
等网络超时错误,这个和AS执行gradle一样需要配置代理。undefined在.android
目录下gradle.properties
文件配置合适的代理,就可以解决这个问题。 然后可能出现Could not find lint-gradle-api.jar
这样的神奇问题,这个的处理方法是:进入到flutter安装的目录下(假定是.flutter),然后修改目录下的.flutter/packages/flutter_tools/gradle/build.gradle
文件,将 repositories { jcenter() maven { url 'https://dl.google.com/dl/android/maven2' } } 修改为:repositories { maven { url 'https://dl.google.com/dl/android/maven2' } jcenter() } (其实就是两个位置调换一下,如果某些资源还是找不到,再在前面加一个google()
)
成功执行后,会在.android/Flutter/build/outputs/aar/
目录下,创建一个flutter-debug.aar
的包文件
(三)在项目的setting.gradle加上如下代码:
代码语言:txt复制setBinding(new Binding([gradle: this]))
evaluate(new File(
settingsDir.parentFile,
'<module_name>/.android/include_flutter.groovy'
))
这里是将Flutter项目导入到AS项目中,不过导入的flutter模块只有java代码,想写dart还是要另外开一个IDE。
(四)然后需要在build.gradle(app)中加入如下依赖:
代码语言:txt复制implementation project(':flutter')
此时sync就一般可以成功了,如果失败了,按照提示逐步解决即可。
笔者这里遇到两个问题,都比较好解决:gradle插件版本问题,flutter模块辛苦3.x以上,需要将主工程的gradle版本升级上去 flutter模块和主工程引用的第三方库版本冲突,常规解决即可,将版本设为一致,或将flutter中的implementation改为api即可
项目中使用Flutter
前面完成了的话,app已经可以run起来了。现在看怎么引入Flutter的代码。
了解了Flutter的知识,其实可以感觉得到,,Flutter中的widget等控件or布局,对于android或iOS来说是透明的,平台只会认为整个Flutter展示的内容是一个view。
所以在android中的用Flutter,就是用一个view去承载Flutter项目。
其实可以理解为flutter就是一个提供了各种绘制方法的view,在Flutter里面的操作就是对view的onDraw方法的控制(还有touch事件)
所以直接当做view去使用的话,就是这样:
代码语言:txt复制View flutterView = Flutter.createView(
MainActivity.this,
getLifecycle(),
"route1"
);
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(600,800);
layout.leftMargin = 100;
layout.topMargin = 200;
activity.addContentView(flutterView, layout);
对应的Flutter的lib中main.dart文件内容是这样:
代码语言:txt复制import 'dart:ui';
import 'package:flutter/material.dart';
void main() => runApp(_widgetForRoute(window.defaultRouteName));
Widget _widgetForRoute(String route) {
switch (route) {
case 'route1':
return SomeWidget(...);
case 'route2':
return SomeOtherWidget(...);
default:
return Center(
child: Text('Unknown route: $route', textDirection: TextDirection.ltr),
);
}
}
window.defaultRouteName
会接受到主项目中传入的路由路径,然后返回对应的widget的,之后这个view就完全可以当做一整个Flutter app去对待了。但它的生命周期是由Activity管理的,所以Flutter也可以用Fragment去承载:
FragmentTransaction tx = fragmentActivity.getSupportFragmentManager().beginTransaction();
tx.replace(R.id.someContainer, Flutter.createFragment("route1"));
tx.commit();
看源码的话,FlutterFragment这里就是将FlutterView wrap了一下,在
onCreateView
里直接返回了FlutterView。
之后对于FlutterView就是完全是在Flutter项目中开发了。
补充
集成到项目工程中时遇到两个问题。
- 一个是Flutter不支持armeabi,而我们项目中库都是armeabi的,只能通过将armeab-v7a强行打入armeabi来处理,这样带来的问题是某些不支持armeabi-v7a的cpu设备会无法运行。(目前没有很好的解决方法,不过现在主流的设备都已经支持armeabi-v7a,倒是问题不大。具体数据有待调查)
- 另一个就是编译时出现错误:
没有初始化虚拟机
,尝试了各种方法,后来发现前面的编译指令应该去掉flutter:
,否则不会打包flutter_assets,这个有点坑~用下面指令就没有问题。
$ ./gradlew assembleDebug
Wrote by Kevin(a2V2aW56aGFuMDQxN0BvdXRsb29rLmNvbQ==)