范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

有赞Flutter混编方案

  背景
  目前准备试水 Flutter,但是多数native开发是不了解Flutter,因此需要设计一种比较"舒服"的集成方式。混编方案方案考量如果直接采用 Flutter 工程结构来作为日常开发,那这部分 Native 开发也需要配置Flutter环境, 相当程度的了解 Flutter 一些技术,成本比较大。同时如果工程耦合,对于开发过程也是很难受的
  基于以上两点思考,针对 Android iOS 有如下方案:Android
  先看下官方的集成方式:# setting.gradle setBinding(new Binding([gradle: this]))   evaluate(new File(          "../managementcenter/.android/include_flutter.groovy" )) 123456# build.gradle dependencies {     implementation project(":flutter")   ........... } 12345
  这种方式使得工程强耦合,虽然便于开发调试,但是违背了第一点,大多数 native 同学都需要配置 Flutter 环境, 成本很大。iOS官方 iOS 混编方案简介
  传送门在native项目Podfile中通过 eval binding特性注入 podhelper.rb脚本,在pod install/update 时执行此脚本,脚本主要处理:Pod本地依赖Flutter引擎(Flutter.framework) 与Flutter插件注册表(FlutterPluginRegistrant)Flutter插件通过flutter packages get指令安装后生成的 .flutter-plugins文件解析,然后Pod本地依赖所有的插件在pod install执行完的钩子 post_install中,获取当前pod target工程对象,导入 Generated.xcconfig配置,其中都为环境变量的配置,主要为后续的xcode_backend.sh脚本执行做准备在构建阶段Build Phases中注入构建是需要执行的xcode_backend.sh脚本,脚本主要完成Flutter产物的构建并将其添加到对应的native工程中去,后续会进一步介绍此脚本优点无缝开发,配置好后就可以只在 Flutter 工程内进行业务开发,无缝同步到 native 工程中不需要单独拆分组件,免去管理组件的版本及发布成本缺点非常耦合,需要修改原有 native 工程配置,需要添加特定脚本去编译 Flutter需要修改原有 pod 的 xcconfig 配置所有团队开发成员都必须要配置 Flutter 开发环境才能编译成功小结
  基于以上思考,同时考虑到某个 Flutter 业务模块可能会引入到不同的 App 中,同时考虑到某个业务实现方式方面的解耦(某个业务可能用 native, flutter, weex 开发),有以下方案(中间产物库每个 Flutter 业务模块都是独立的):
  Android:
  iOS:
  Flutter产物结构Android
  iOS
  关于编译模式了解更多可参考查看 Flutter的编译模式。Flutter产物收集Android
  在Android 端集成Flutter较为简单,只需要获取到上文所讲的Flutter产物即aar文件。但是由于插件文件散落每次获取比较麻烦所以目前简单用脚本收集。
  脚本收集主要是依靠项目里 .flutter_plugins 文件,该文件会记录flutter项目中引用的插件名以及本地路径等,因此可以通过该路径抓取插件的 aar 文件。from shutil import copyfile   import os   import requests  # 抓取文件类型 BuildRelease = True   aarType = "-release.aar" if BuildRelease else "-debug.aar"  pluginFilePath = "../.flutter-plugins"  # 当前项目的flutter.aar currentFlutterPath = "../.android/Flutter/build/outputs/aar/"  # 输出地址 outputFilePath = os.path.abspath("flutter_aar.py").replace("flutter_aar.py", "aars/")  endPath = "android/build/outputs/aar/"  def collect_aar(plugins):       all_collection_success = True     if os.path.exists(outputFilePath):         print("copy aar to: " + outputFilePath)     else:         print("target path: " + outputFilePath + " not exist")         os.makedirs(outputFilePath)         print("create target path: " + outputFilePath)      for key, value in plugins.items():         aar_path = value + key + aarType         try:             copyfile(aar_path, outputFilePath + key + aarType)             print("copy flutter aar success at path: " + aar_path)         except IOError:             all_collection_success = False             print("copy flutter aar error at path: " + aar_path)     pass  file_object = open(pluginFilePath, "r")   try:       plugin_map = {}     for line in file_object:         array = line.split("=")         plugin_map[array[0]] = array[1].replace(" ", "") + endPath      plugin_map["flutter"] = currentFlutterPath     collect_aar(plugin_map) finally:       file_object.close() 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  目前该python脚本只抓取 Release 的 aar 文件,如果需要获取 debug 的可以手动修改BuildRelease = False   1
  执行抓取脚本 ./flutter_aar.sh#!/usr/bin/env bash  cd ..   cd .android   echo "start clean"   ./gradlew clean echo "start assembleRelease"   ./gradlew assembleRelease cd ..   cd android-build  echo "clean old aar file"   rm -rf aars  echo "start copy aar file"   # 只抓取release python flutter_aar.py  echo "copy aar file finish"   12345678910111213141516171819
  脚本执行完 Flutter 产物 aar 文件统一生成在根目录下 android-build 文件夹中。
  iOS
  通过查看 Flutter 编译脚本 xcode_backend.sh 和测试单独引入编译产物,发现其实 只要拥有Flutter的编译产物,宿主项目就可以接入Flutter的功能。脚本简单分析engine/Flutter.framework Flutter 核心库拷贝 -> Flutter.framework  if [[ -e "${project_path}/.ios" ]]; then       RunCommand rm -rf -- "${derived_dir}/engine"       mkdir "${derived_dir}/engine"       RunCommand cp -r -- "${flutter_podspec}" "${derived_dir}/engine"       RunCommand cp -r -- "${flutter_framework}" "${derived_dir}/engine"       RunCommand find "${derived_dir}/engine/Flutter.framework" -type f -exec chmod a-w "{}" ;     else       RunCommand rm -rf -- "${derived_dir}/Flutter.framework"       RunCommand cp -r -- "${flutter_framework}" "${derived_dir}"       RunCommand find "${derived_dir}/Flutter.framework" -type f -exec chmod a-w "{}" ;     fi 1234567891011debug 模式下 Dart 业务代码编译(JIT) -> App.framework  RunCommand eval "$(echo "static const int Moo = 88;" | xcrun clang -x c           ${arch_flags}           -dynamiclib           -Xlinker -rpath -Xlinker "@executable_path/Frameworks"           -Xlinker -rpath -Xlinker "@loader_path/Frameworks"           -install_name "@rpath/App.framework/App"           -o "${derived_dir}/App.framework/App" -)" 1234567非 debug 模式下 Dart 业务代码编译(AOT) -> App.framework  RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics                    ${verbose_flag}                                                                build aot                                                                      --output-dir="${build_dir}/aot"                                                --target-platform=ios                                                          --target="${target_path}"                                                      --${build_mode}                                                                --ios-arch="${archs}"                                                          ${local_engine_flag}                                                           ${track_widget_creation_flag} 12345678910资源文件等打包 -> flutter_assets  StreamOutput " ├─Assembling Flutter resources..."     RunCommand "${FLUTTER_ROOT}/bin/flutter" --suppress-analytics                    ${verbose_flag}                                                                build bundle                                                                   --target-platform=ios                                                          --target="${target_path}"                                                      --${build_mode}                                                                --depfile="${build_dir}/snapshot_blob.bin.d"                                   --asset-dir="${derived_dir}/App.framework/flutter_assets"                      ${precompilation_flag}                                                         ${local_engine_flag}                                                           ${track_widget_creation_flag} 123456789101112方案分析设计
  插件统一编译成.a库,添加对应头文件App.framework 及 engine/Flutter.framework 添加目前初期 demo 将上述生成的产物统一放入到私有库当中,然后 native 宿主工程 pod 依赖此库,只需要在使用 Flutter 代码的地方 import 对应的头文件即可正常使用脚本编写  echo "===清理flutter历史编译==="   flutter clean    echo "===重新生成plugin索引==="   flutter packages get    echo "===生成App.framework和flutter_assets==="   flutter build ios --debug    echo "===获取所有plugin并找到头文件==="   while read -r line   do        if [[ ! "$line" =~ ^// ]]; then           array=(${line//=/ })           plugin_name=${array[0]}           cd .ios/Pods           echo "生成lib${plugin_name}.a..."           /usr/bin/env xcrun xcodebuild build -configuration Release ARCHS="arm64 armv7" -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphoneos -quiet           /usr/bin/env xcrun xcodebuild build -configuration Debug ARCHS="x86_64" -target ${plugin_name} BUILD_DIR=../../build/ios -sdk iphonesimulator -quiet           echo "合并lib${plugin_name}.a..."           lipo -create "../../build/ios/Debug-iphonesimulator/${plugin_name}/lib${plugin_name}.a" "../../build/ios/Release-iphoneos/${plugin_name}/lib${plugin_name}.a" -o "../../product/lib${plugin_name}.a"           echo "复制头文件"           classes=${array[1]}ios/Classes           for header in `find "$classes" -name *.h`; do               cp -f $header "../../product/"           done       else            echo "读取文件出错"       fi   done < .flutter-plugins    echo "===生成注册入口的二进制库文件==="   for reg_enter_name in "FlutterPluginRegistrant"   do       echo "生成libFlutterPluginRegistrant.a..."       /usr/bin/env xcrun xcodebuild build -configuration Release ARCHS="arm64 armv7" -target FlutterPluginRegistrant BUILD_DIR=../../build/ios -sdk iphoneos       /usr/bin/env xcrun xcodebuild build -configuration Debug ARCHS="x86_64" -target FlutterPluginRegistrant BUILD_DIR=../../build/ios -sdk iphonesimulator       echo "合并libFlutterPluginRegistrant.a..."       lipo -create "../../build/ios/Debug-iphonesimulator/FlutterPluginRegistrant/lib$FlutterPluginRegistrant.a" "../../build/ios/Release-iphoneos/FlutterPluginRegistrant/libFlutterPluginRegistrant.a" -o "../../product/libFlutterPluginRegistrant.a"       echo "复制头文件"       classes="../Flutter/FlutterPluginRegistrant/Classes"       for header in `find "$classes" -name *.h`; do           cp -f $header "../../product/"       done   done 123456789101112131415161718192021222324252627282930313233343536373839404142434445后续规划脚本优化,添加自动pod库检测及上传App.framework/Flutter.framework 体积太大,放到git仓库不太友好,考虑后续上传到CDN,然后在pod安装的时候预先执行脚本把两个产物拉下来Flutter产物上传Android
  上面产物搜集完成后,需要上传 maven 仓库,方便集成以及版本控制apply plugin: "youzan.maven.upload"  zanMavenUpload {       version = "0.0.2"     childGroup = "flutter-apub" }  uploadItems {       "fluttertoast" {         targetFile = file("../../android-build/aars/fluttertoast-release.aar")     }      "image_picker" {         targetFile = file("../../android-build/aars/image_picker-release.aar")     }      ............ } 123456789101112131415161718
  因此引用链如下:Android
  iOS
  总结
  以上比较全面的描述了有赞的 Flutter 混编方案,目前有赞已经在内部使用的App上使用 Flutter 开发了一些页面作为试点。后续会考虑在线上 App 试点,目前正在进行 Flutter 基础库的搭建,之后会专门有文章分享。

现阶段换购i5,8500合不合适?i36100换成i58500还是有明显提升的,我们可以先简单对比一下二者的参数i36100采用Intel14nm工艺,SkyLake架构,2核心4线程,主频3。7GHz,带有HD5三季报巨震,中概最悲观的时刻从今年年初以来,监管逐步加强对互联网行业的规范力度,对多个细分行业的可持续发展产生深远影响。比较直观的是,中概类的基金基本都回撤了30以上,中概互联ETF年初高位至今跌幅超40。头英伟达公布第三季度财报营收达71。03亿美元品玩11月18日讯,英伟达今天在美股盘后发布了第三季度财报。根据财报显示,英伟达第三季度营收达71。03亿美元,同比增长50。根据财报显示,英伟达第三季度净利润为24。64亿美元,华为鸿蒙系统已向老旗舰机推送了,大家升级以后感觉怎么样?我的mate9使用鸿蒙系统之后,一切都很好。感觉比原来的系统更加顺畅。我以前用的是苹果,再以前用过安卓机,苹果跟安卓比,最大的优点是系统顺畅,基本没有卡顿,缺点是具体操作不够方便,马斯克的星链计划是不是超过了5G和6G技术啊国内有什么对策吗?有对策,我们无视,沉默,看不到听不到就没有威胁星链计划就是一个梦想,白天做梦的梦!没有地面站支持,基本上等于废物,但汽车可以直联卫星,自动驾驶方面是有用的,跟5G6G没什么大关系星智能安全帽如何实现安全管理?通过在保留了传统安全帽所有国家安全标准基础上,增加智能处理模块,实现远程安全管理。其实是这样,智能穿戴它不仅有比如说手环,帽子,眼镜之类穿戴单品终端,更重要的部分,是它集成的模块包哪些iOS应用让你用了很满意并能提高生活质量?即时数据传输使用iPhone可以直接通过分享页面的隔空投送功能,向附近的Apple产品即时传输数据,即便是体积非常大的视频也能够在数秒内传输完毕,而且不受局域网络限制,非常方便。i拒绝盲目选购智能马桶智能马桶可以说是当今社会大多数人家里必不可少的智能家电了,但是很多人并不了解智能马桶,踩过的坑更是不计其数作为知道并且了解智能马桶的人,今天给想买智能马桶的小伙伴们七条建议!!建议对华为平板的一点吐槽!!!究竟是生产力还是视频播放器首先,这是至今为止,购买华为品牌最为失望的一个产品!因工作原因,不常待在办公室,基本开车在市内办事,偶尔会需要用到办公软件作图软件这些,笔记本虽然号称便携,但毕竟携带起来还是不方便没有IT部的中小企业,有什么办法做好公司的信息化管理?首先信息化管理不仅仅是IT部门的事情,没有IT部的情况下,仍然需要梳理相关痛点,针对痛点可以直接选用SaaS应用如财务系统您可以考虑大账房智能财税,好会计,精斗云会计等,进销存可以天融信预中标中国电信安全数据中心软件项目运营商业务取得突破中证网讯(王珞)近日,中国电信发布2021年安全数据中心之态势感知模块(集团及31省)建设工程省态势感知软件中标候选人公示,天融信(002212)成功入围。此次中标,是天融信大数据
清算电子烟撰文新经济沸点郭娟低调许久的电子烟,近来的股市表现可圈可点。1月22日晚,悦刻RELX美国纽交所上市,开盘暴涨104,触发熔断停牌,五分钟后恢复交易,截至当日收盘,涨了145。9。撬装加油站市场怎么样?成品油需求大,油价上涨趋势明显。从去年11月19日开始,油价就一直保持着上涨态势。虽然在今年的三月末,国内成品油价格史无前例地进行了下调,但在之后的调整中,除了有2次不作调整以外,撬装加油站的办理条件和流程(中宝石油资讯)目前,在全国多个省市自治区已经出现许许多多撬装式加油站(企业加油站)的身影,以其建站成本低,安全环保,手续简便等特点得到很多企业的青睐,而撬装加油站的使用,很明显的一个作用就是节省全新奥迪Q5L颜值动力兼具,是你不容错过的好车在国内近些年的汽车市场中,在中型SUV这一级别中,可以说消费者在选购时总是在犹豫徘徊,但是根据目前的市场销量表现来看,还是全新奥迪Q5L这一款车表现的更出色一些,它也是上市不久的一豪华中型SUV之争,全新奥迪Q5L更胜一筹凭借着出众的颜值舒适的驾乘体验以及诱人的终端优惠,全新奥迪Q5L成为了炙手可热的豪华中型SUV,而在豪华中型SUV领域,奔驰GLC的表现也是相当强劲。但小编依旧很喜欢全新奥迪Q5L高级感爆棚,全新奥迪Q5L让你纵享尊贵在中型SUV细分领域,同级别车型竞争激烈个个都实力强悍。全新奥迪Q5L以全新的面貌面向大家,也给消费者带来了全新的驾驶体验,接下来就让我们一起来看看吧。犀利时尚的外观设计外观方面,2021新款SUV重磅来袭,全新奥迪Q5L成为新巨头2021年4月19日在上海车展,全新奥迪Q5L隆重出展,并赢得了汽车消费市场的广泛关注。同年5月28日,全新奥迪Q5L正式进入市场,这一款新型车型一共上市了8款不同的车型,其区别在云米AI燃气灶,智慧生活灶起来现代年轻人的快节奏生活让做饭日益奢侈,你有多久没有好好为自己做一顿饭了?民以食为天,吃饭做饭,不只是饱口腹之欲,更是凝聚家庭的重要仪式,每个看来寻常的环节里,都有着爱意的传递。在这家中被褥都是螨虫?这款吸尘器不仅能除螨,还能除菌家里即将装修完工,家里还缺一台吸拖一体的清洁器,正好双十一入手一台睿米家的无线吸尘器。今天收到快递的确感受到睿米产品的用心。这款睿米吸尘器的包装用的是可提拉形式的包装,能够便捷提拿追光是一种信仰,不是高富帅的专利,拨草灵蛇P98最近将键鼠全升级为RGB光效,唯独剩下桌面垫没有换掉,但是每次开启键鼠光效的时候总觉得有点美中不足,知道应该把鼠标垫也换了。市面上专业游戏发光垫还是蛮贵的,对于笔者这种不是发烧级别联通信号不好乱收费?现在三大运营商之间可以携号转网了近日,随着5G套餐的推出和使用,许多用户发现运营商推出的套餐有着各种花样。于是就有一部分网友表示手上的联通卡信号太差了,还经常出现乱收费等情况,他们对此表示非常的不满意。他们想转网