之前开发了一个纯Flutter的项目,结果接到个新的需求需要使用Flutter单独开一个模块集成到原有的android项目中
下面分享一下如何集成现有的项目和如何继承以及碰到的问题
1.首先第一步 修改gradle
因为 Flutter 当前仅支持为 x86_64,armeabi-v7a 和 arm64-v8a 构建预编(AOT)的库 所以我们需要修改gradle的文件限制 APK 中支持的架构,从而避免 libflutter.so找不到引起的崩溃
android {
//...
defaultConfig {
ndk {
// Filter for architectures supported by Flutter.
abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
}
}
}
2.新建一个FlutterModel的工程
3.在android中添加Flutter的依赖
在添加Flutter依赖的时候一共有两种方式
1.使用本地文件(建议自己本地调试的时候使用) 因为方便修改和调试
(1)修改 settings.gradle
image.png
(2)修改gradle引入Flutter
dependencies {
implementation project(':flutter')
}
2.使用aar文件 因为所有工程统一使用jenkins打包所以我们放在本地肯定是不合适的
说以我们需要 打包aar并上传服务器
@echo off
::start cmd /C
flutter clean
flutter build aar --build-number version
# 定义用于aar、pom文件目录存放的数组
aars=()
poms=()
# 指定打包后本地仓库的目录,由于这里将此脚本放在flutter module根目录,因此直接配置了flutter module根目录下相对目录
targetPath="build/host/outputs/repo"
# 定义遍历找到所有pom文件和aar文件的函数
# 参数$1:当前查找的目录名
function findAarPom(){
echo "查找此目录是否有aar及pom:$1"
targetDir=`ls $1`
for fileName in $targetDir
do
if [[ -d $1"/"$fileName ]]; then
# 还是目录,则递归找下一级
findAarPom $1"/"$fileName
else
# 如果是文件,判断后缀,如果符合期望,则将文件路径拼接好放于对应数组最后一位
if [[ ${fileName:0-4} == '.aar' ]]; then
aars[${#aars[@]}]=$1"/"$fileName
elif [[ ${fileName:0-4} == '.pom' ]]; then
poms[${#poms[@]}]=$1"/"$fileName
fi
fi
done
}
findAarPom $targetPath
echo "============"
echo "aar有:《共${#aars[@]}个》"
echo "${aars[@]}"
echo "pom有:《共${#poms[@]}个》"
echo "${poms[@]}"
echo "============"
# 一个aar文件必然对应会有一个pom文件,如果数量不对,一定是打包出错
if [[ ${#aars[@]} -ne ${#poms[@]} ]]; then
echo "-- !!! pom文件与aar不对称,请检查aar打包配置,上传任务 退出 !!! --"
exit 1
fi
if [[ ${#aars[@]} == 0 ]]; then
echo "-- !!! 未找到aar文件,请检查aar打包配置,上传任务 退出 !!! --"
exit 1
fi
# 定义将目标pom及aar上传到maven指定仓库的函数
# 参数$1:为pom文件
# 参数$2:为aar文件
function upload(){
echo "开始上传:"
echo $1
echo $2
# mvn上传命令,这里由于将上传用户名密码配置于全局maven settings.xml,则无需再指定用户名密码
mvn deploy:deploy-file \
-DpomFile="$1" \
-DgeneratePom=false \
-Dfile="$2" \
-Durl="你自己的maven服务器地址" \
-DrepositoryId="deploymentRepo" \
-Dpackaging=aar
}
# 循环上传
for (( i=0;i<${#aars[@]};i++ )); do
echo "正在处理第$[$i+1]个,共${#aars[@]}个"
upload "${poms[$i]}" "${aars[$i]}"
done
上传完成后在android中引用
debugImplementation 'com.xyy.saas_flutter:flutter_debug:1.1.7-SNAPSHOT'
releaseImplementation 'com.xyy.saas_flutter:flutter_release:1.1.7-SNAPSHOT'
在开发中遇到的问题
1.关于android和Ios中的跳转传参问题
这个问题在android端还是比较方便的 但是的在Ios端并不怎么好实现
最终决定使用flutter_boost来完成android和Ios与Flutter的通信操作
flutter_boost github地址:https://github.com/alibaba/flutter_boost
集成文档:https://github.com/alibaba/flutter_boost/blob/master/INTEGRATION.md
集成文档给出了 但是没有android的 尴尬
下满分享下android的集成
(1)在flutter的 pubspec.yaml工程中添加
flutter_boost:
git:
url: 'https://github.com/alibaba/flutter_boost.git'
ref: 'v1.17.1-hotfixes'
(2)修改android工程
使用本地工程的时候需要在工程共添加
implementation project(':flutter_boost')
使用aar的时候不需要添加
(3)在android工程中添加对应的条状路由配置
public class PageRouter {
//在map中添加对应路由的key和value
public final static Map<String, String> pageName = new HashMap<String, String>() {{
put(NAME, "name");
}};
public static void openPageByUrl(Context context, String url, Map<String, Object> params) {
openPageByUrl(context, url, params, 0);
}
public static void openPageByUrl(Context context, String url, Map<String, Object> params, int requestCode) {
String path = url.split("\\?")[0];
LogUtils.i("openPageByUrl", path);
try {
if (pageName.containsKey(path)) {
Intent intent = MyFlutterActivity.withNewEngine().url(Objects.requireNonNull(pageName.get(path))).params(params)
.backgroundMode(MyFlutterActivity.BackgroundMode.opaque).build(context);
if (context instanceof Activity) {
Activity activity = (Activity) context;
activity.startActivityForResult(intent, requestCode);
} else {
context.startActivity(intent);
}
}
} catch (Throwable t) {
LogUtils.e(t.getMessage());
}
}
}
(4)在使用默认的flutter_boost启动界面的时候可能碰到状态栏丢失的情况
所以最好集成BoostFlutterActivity写一个新的activity方便处理状态栏和activity进出动画
public class MyFlutterActivity extends BoostFlutterActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//重写设置状态栏
StatusBarUtil.setColor(this, ContextCompat.getColor(this, R.color.colorWhite), 0);
StatusBarUtil.StatusBarLightMode(this);
}
//这个必须要写 否则不生效
public static NewEngineIntentBuilder withNewEngine() {
return new NewEngineIntentBuilder(MyFlutterActivity.class);
}
@Override
public void finish() {
super.finish();
//动画
overridePendingTransition(R.anim.activity_trans_right_in, R.anim.activity_trans_right_out);
}
}
(5)跳转并传参
//params 传多个参数可以使用json的形式
PageRouter.openPageByUrl(this, key, params);
2.在flutter中的网络框架使用的dio结果在ios的弹出loading的时候出现卡顿现象
解决方式:1.服务换证书 (但是后台太忙暂时没有支持的人员)
2.ios使用原生的loading解决
3.在使用dio的时候出现ios部分手机 网络请求缓慢问题
解决方法:请求的时候使用http 2.0协议
插件地址:https://github.com/flutterchina/dio/tree/master/plugins/http2_adapter
网友评论