IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Flutter 工程化搭建(Android端) -> 正文阅读

[移动开发]Flutter 工程化搭建(Android端)

为了积极拥抱新技术并优化RN的性能问题,所以决定在新业务需求中引入Flutter技术栈

Flutter混合栈开发大致可以分为一下两种模式

native工程直接依赖开发

具体接入方式为,先在setting.gradle 中加入如下代码:

setBinding(new?Binding([gradle:?this]))
evaluate(new?File(
????????settingsDir,
????????'../../Flutter?Module工程根目录/.android/include_flutter.groovy'
))

其次在App的build.gradle 中加入如下代码:

?implementation?project(':flutter')

最后在主工程的build.gradle 中加入如下代码即可:

repositories?{
buildscript?{
????????maven?{
????????????url?'http://download.flutter.io'
????????}
????}
}
????
allprojects?{
????repositories?{
????????maven?{
????????????url?'http://download.flutter.io'
????????}
????}
}

native工程接入aar

新建Flutter module工程

flutter?create?-t?module?xx_module

目录结构如下

xx_modlue?
??????????-?.android?//?Android测试工程
??????????-?.ios??//?iOS测试工程
??????????-?lib??//?Flutter主工程
????????????????-?main.dart?//?Flutter入口文件
??????????-?pubspec.yaml??//?Flutter三方包配置文件

Flutter中提供了将module打包成aar的命令,生成的aar文件路径为 xx_modlue/build/host/outputs/repo

flutter?build?aar

将生成的aar文件引入Android开发工程即可完成aar的引用

到目前为止整个aar的引入基本是可以正常开发的,但是存在问题,那就是在每次开发都需要手动的将生成的aar包复制到主工程中进行依赖,不仅操作麻烦而且会出错,所以讲Flutter打包及引入流程变成日常开发常用的模式是最佳实践

flutter 打包上传流程分析:

为符合日常开发流程,需要将Flutter打成的aar文件上传至maven,因此首要任务就是解决将aar上传至maven问题

查看生成的aar目录下面的pom文件会发现主工程依赖的第三方aar包也会被下载至xx_modlue/build/host/outputs/repo路径下,pom文件如下:

<project?xsi:schemaLocation="http://maven.apache.org/POM/4.0.0?http://maven.apache.org/xsd/maven-4.0.0.xsd"?xmlns="http://maven.apache.org/POM/4.0.0"
????xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
??<modelVersion>4.0.0</modelVersion>
??<groupId>com.xxx.flutter</groupId>
??<artifactId>xxx</artifactId>?
??<version>release-0.0.7</version>
??<packaging>aar</packaging>
??<dependencies>
????<dependency>
??????<groupId>io.flutter</groupId>
??????<artifactId>flutter_embedding_release</artifactId>
??????<version>1.0.0-af51afceb8886cc11e25047523c4e0c7e1f5d408</version>
??????<scope>compile</scope>
????</dependency>
????<dependency>
??????<groupId>io.flutter</groupId>
??????<artifactId>armeabi_v7a_release</artifactId>
??????<version>1.0.0-af51afceb8886cc11e25047523c4e0c7e1f5d408</version>
??????<scope>compile</scope>
????</dependency>
????<dependency>
??????<groupId>io.flutter</groupId>
??????<artifactId>arm64_v8a_release</artifactId>
??????<version>1.0.0-af51afceb8886cc11e25047523c4e0c7e1f5d408</version>
??????<scope>compile</scope>
????</dependency>
????<dependency>
??????<groupId>io.flutter</groupId>
??????<artifactId>x86_64_release</artifactId>
??????<version>1.0.0-af51afceb8886cc11e25047523c4e0c7e1f5d408</version>
??????<scope>compile</scope>
????</dependency>
??</dependencies>
</project>

分析pom文件可知在上传主工程生成的aar的时候我们还需要将下载下来的第三方aar上传至maven库,因此我们得知具体工程化脚本流程如下:

1、获取生成的aar路径
2、上传第三方依赖的aar文件
3、更新主工程aar的artifactId
4、上传主工程aar文件

具体脚本如下:

deploy_aar(){
????mvn?deploy:deploy-file?\
????-DpomFile="$FILE_PATH/$NAME.pom"?\
????-DgeneratePom=false?\
????-Dfile="$FILE_PATH/$NAME.aar"?\
????-Durl="http://xxx.xxx.xxx:xxx/repository/public/"?\
????-DrepositoryId="nexus"?\
????-Dpackaging=aar?\
????-s="mvn-settings.xml"?\
????-Dversion="$VERSION"
}

projectDir=`pwd`

#?清除Flutter生成文件
flutter?clean

#?获取pub包
flutter?pub?get

#?删除文件夹
rm?-rf?`pwd`/build/host/outputs/repo/


#?修改版本号
group="com.xxx.flutter"
type="release"
#type="debug"
#type="profile"
version="${type}-0.0.7"
artifactId="xxx"


echo?"替换Flutter/build.gradle?中的group?为${group}"
path=`pwd`/.android/Flutter/build.gradle
sed?-i?''?'29s/^.*$/group?"'${group}'"/'??${path}
echo?"替换Flutter/build.gradle?中的version?为${version}"
path=`pwd`/.android/Flutter/build.gradle
sed?-i?''?'30s/^.*$/version?"'${version}'"/'??${path}


#?打包AAR
flutter?build?aar?--no-debug?--no-profile

#?找到AAR并上传
path=`pwd`
#?shellcheck?disable=SC2006
p=`find?${path}/build/host/outputs/repo?-type?f??-name?"*${type}*.aar"`
echo?"${p}"


array=(${p//'\n'/})
currentName=""
currentPath=""
currentPom=""
currentDir=""

#?shellcheck?disable=SC2068
for?item?in?${array[@]}
do
????resFile=`basename?${item}`
????echo?"${item}"
????result=$(echo?${resFile}?|?grep?"flutter_release")
????if?[[?"$result"?==?""?]]
????then
??????lenght=${#item}
??????sub=${item:0:${lenght}-3}
??????pom="${sub}pom"
??????resFileLenght=${#resFile}
??????subDir=${item:0:${lenght}-${resFileLenght}}
??????curName=`echo?${resFile}?|?cut?-d?"-"?-f?2`
??????curNameLenght=${#curName}
??????subVersion=${curName:0:${curNameLenght}-4}
??????nameLenght="${#resFile}"
??????subName=${resFile:0:${nameLenght}-4}
??????export?FILE_PATH="${subDir}"
??????export?NAME="${subName}"
??????export?VERSION=${subVersion}
??????deploy_aar
????else
??????nameLenght="${#resFile}"
??????subName=${resFile:0:${nameLenght}-4}
??????currentName="${subName}"
??????currentPath=${item}
??????currentPath=${item}
??????lenght=${#item}
??????sub=${item:0:${lenght}-3}
??????currentPom="${sub}pom"
??????resFileLenght=${#resFile}
??????subDir=${item:0:${lenght}-${resFileLenght}}
??????currentDir=${subDir}
????fi
done

cd?"${currentDir}"
echo?`pwd`
mv?"${currentName}.aar"?"${artifactId}-${version}.aar"
mv?"${currentName}.pom"?"${artifactId}-${version}.pom"
cd?${projectDir}
echo?`pwd`

currentName="${artifactId}-${version}"
currentPath="${currentDir}${currentName}.aar"
currentPom="${currentDir}${currentName}.pom"
echo?"current?name?is?${currentName}"
echo?"current?path?is?${currentPath}"
echo?"currentPom?is?${currentPom}"
echo?"替换pom?artifactId为${artifactId}"
sed?-i?''?'6s/^.*$/??<artifactId>'${artifactId}'<\/artifactId>?/'??${currentPom}
echo?"currentDir?is?${currentDir}"
echo?"currentVersion?is?${version}"


export?FILE_PATH="${currentDir}"
export?NAME="${currentName}"
export?VERSION=${version}
deploy_aar

上传maven成功后,主工程依赖Flutter代码就和添加第三方SDK流程一致了。

「选型对比」

名称优点缺点
native工程直接依赖开发接入快工程结构复杂,无法将Flutter开发从native开发流程中剥离
native工程接入aarFlutter开发与native开发流程解耦初期接入流程复杂

最终选择为通过maven方式接入aar方便后续拓展

Flutter 混合栈选型

在完成Flutter混合开发接入流程后,会有混合栈管理问题,在混合方案中解决的主要问题是如何去处理交替出现的Flutter和Native页面。综合目前的开源框架,选型为FlutterBoost

flutterBoost Flutter端接入:

FlutterBoost.singleton.registerPageBuilders(<String,?PageBuilder>{
??????testhome:?(String?pageName,?Map<dynamic,?dynamic>?params,?String?_)?=>
??????????MyHomePage(title:?''),
??????shoppingcar:?(String?pageName,?Map<dynamic,?dynamic>?params,?String?_)?{
????????String?platformItemNo?=?'';
????????if?(params.containsKey("platformItemNo"))?{
??????????platformItemNo?=?params['platformItemNo'];
??????????NativeChat.print(platformItemNo);
????????}
????????return?ShoppingCar(platformItemNo:?platformItemNo);
??????},
??????login:?(String?pageName,?Map<dynamic,?dynamic>?params,?String?_)?=>
??????????LoginPage(),
??????overlay:?(String?pageName,?Map<dynamic,?dynamic>?params,?String?_)?=>
??????????OverlayPage(),
????});

android端接入:

application 初始化代码:

val?router?=
????????????INativeRouter?{?context,?url,?urlParams,?requestCode,?exts?->
????????????????PageRouter.openPageByUrl(context,?url,?urlParams)
????????????}

????????val?boostLifecycleListener?=?object?:?FlutterBoost.BoostLifecycleListener?{
????????????override?fun?onEngineCreated()?{
????????????}

????????????override?fun?onPluginsRegistered()?{
????????????}

????????????override?fun?beforeCreateEngine()?{
????????????}

????????????override?fun?onEngineDestroy()?{
????????????}

????????}

????????val?platform?=?FlutterBoost.ConfigBuilder(application,?router)
????????????.isDebug(BuildConfig.DEBUG)
????????????.whenEngineStart(FlutterBoost.ConfigBuilder.ANY_ACTIVITY_CREATED)
????????????.renderMode(FlutterView.RenderMode.texture)
????????????.lifecycleListener(boostLifecycleListener)
????????????.build()
????????FlutterBoost.instance().init(platform)

路由配置代码

//?PageRouter?路由跳转及配置页面
object?PageRouter?{
????/**
?????*?路由映射
?????*/
????val?pageName:?HashMap<String?,?String?>?=
????????object?:?HashMap<String?,?String?>()?{
????????????init?{
????????????????put("xxxx://shoppingCar",?"shoppingCar")
????????????????put("xxxx://login",?"login")
????????????????put("xxxx://home",?"home")
????????????????put("xxxx://overlay",?"overlay")
????????????}
????????}
????const?val?SHOPPING_CAR?=?"xxxx://shoppingCar"
????const?val?LOGIN_PAGE?=?"xxxx://login"
????const?val?OVERLAY?=?"xxxx://overlay"
????const?val?BUYER_PRODUCT_DETAIL?=?"xxxx://buyer/productdetail"
????const?val?TEST_SECOND?=?"xxxx://testSecond"

????@JvmOverloads
????fun?openPageByUrl(
????????context:?Context,
????????url:?String,
????????params:?Map<*,?*>?,
????????requestCode:?Int?=?0
????):?Boolean?{
????????val?path?=?url.split("\\?").toTypedArray()[0]
????????Log.i("openPageByUrl",?path)
????????return?try?{
????????????when?{
????????????????pageName.containsKey(path)?->?{
????????????????????val?intent?=
????????????????????????BoostFlutterActivity.withNewEngine().url(pageName[path]!!)
????????????????????????????.params(params!!)
????????????????????????????.backgroundMode(BoostFlutterActivity.BackgroundMode.opaque)
????????????????????????????.build(context)
????????????????????if?(context?is?Activity)?{
????????????????????????context.startActivityForResult(intent,?requestCode)
????????????????????}?else?{
????????????????????????context.startActivity(intent)
????????????????????}

????????????????????return?true
????????????????}
????????????????url.startsWith(TEST_SECOND)?->?{
????????????????????context.startActivity(
????????????????????????Intent(
????????????????????????????context,
????????????????????????????SecondActivity::class.java
????????????????????????)
????????????????????)
????????????????????return?true
????????????????}
????????????????else?->?false
????????????}
????????}?catch?(t:?Throwable)?{
????????????false
????????}
????}
}

native 跳转逻辑

//?初始化channel通知

?FlutterBoost.instance().channel().addMethodCallHandler?{?call,?result?->
????????????when?(call.method)?{
????????????????"baseUrl"?->?{
????????????????????result.success(ApiConstant.getApiUrl())
????????????????}
????????????}
????????}

//?跳转代码

?val?params?=?hashMapOf<String,?String>()
????????????params["param"]?=?param
????????????PageRouter.openPageByUrl(this,?PageRouter.SHOPPING_CAR,?params)

Flutter 测试环境搭建

在混合开发的工程中被吐槽最多的大概就是测试了吧,和native打包在一起调试费时费力,对前端开发要求高需要了解native的基本流程

???????

?

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-08-06 09:57:05  更:2021-08-06 09:57:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/17 10:47:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码