GMTC2018-《基于Google Flutter的移动端跨平台应用实践》 王树彬
2020-03-01 301浏览
- 1.闲⻥鱼Flutter应⽤用实践 王树彬 阿⾥里里巴巴-闲⻥鱼 架构负责⼈人
- 2.
- 3.
- 4.• 闲⻥鱼为什什么使⽤用Flutter • Flutter与Native混合开发实践 • Hybrid⼯工程实践 - 研发时 • Hybrid栈管理理 - 运⾏行行时 • Hybrid⻚页⾯面组件 • Flutter通⽤用问题实践 • 详情⻚页⻚页⾯面框架 • 图⽚片缓存注意事项 • 上线效果 • 线上Crash率 • 详情⻚页性能对⽐比 • ⼩小结
- 5.Flutter,⼀一种新的可能性 性能 Flutter or 动态性 PhoneGap Reactive Native Weex
- 6.⾼高性能⽅方案原理理 Linear layout, paint Structural Repainting No JS Bridge Skia OpenGL/Vulkan/Metal ⾼高性能 60FPS编程 很好的两端⼀一致性 复杂交互 AOT Dart JIT Machine Code Script/Bytecode Release模式 快速、可预测 开发模式 更更快的开发周期
- 7.闲⻥鱼商品详情⻚页⾯面(Flutter) 混合栈 视频 动画 Native组件 多图 盖楼
- 8.• 闲⻥鱼为什什么使⽤用Flutter • Flutter与Native混合开发实践 • Hybrid⼯工程实践 - 研发时 • Hybrid栈管理理 - 运⾏行行时 • Hybrid⻚页⾯面组件 • Flutter通⽤用问题实践 • 详情⻚页⻚页⾯面框架 • 图⽚片缓存注意事项 • 上线效果 • 线上Crash率 • 详情⻚页性能对⽐比 • ⼩小结
- 9.Flutter Hybrid⼯工程实践
- 10.Flutter默认⼯工程结构
- 11.Hybrid⼯工程的问题 已有⼯工程⽬目录 iOS(git&cocoapods) ? Android(git&gradle) Flutter⼯工程⽬目录 iOS(git&cocoapods) Android(git&gradle) Flutter(git&pub) 如何基于现有⼯工程搭建? 如何⽀支持过渡期的Flutter&Native双开发模式? 如何与现有构建⼯工具集成?
- 12.⼯工程结构 & 双开发模式 以前的⼯工程 新的⼯工程(Flutter&Native/Weex) iOS(git&cocoapods) Android(git&gradle) Flutter App Repo(pub) iOS(git subm&cocoapods) Android(git subm&gradle) Flutter(git submodule) Flutter产物 iOS(git&cocoapods) Android(git&gradle) Submodule引⼊入现有⼯工程 Flutter中间产物 Flutter Team 拆解Flutter构建逻辑,修改gradle和pods脚本 Native/Weex Team
- 13.Hybrid⼯工程修改点 ਧګHQJLQH Engine编译(如ARMv7) ݎӾכ೮කᑞਧ ᛔᤈץද׀ള॔ץݗᳯ᷌ فݳਥොƉ[ ᚕ॒ቘग़ଘݣग़ຝԾᇔ૧ official bugfix FKHUU\SLFN ਧګӨᛔᤈEXJƉ[ SXVK engine.version ਥොflutterՙପ engine(xianyu branch) ਧګƊXWWHU ୌਧګDUPHDEL JFOLHQWV\QF ୌս۸SU HQJLQHԾᇔJLWᓕቘ engineGHSV repo JQ QLQMD )OXWWHUӱۓդᎱ SXE 3DFNDJHV 私有仓库 ƊXWWHUݎ Pub Server1 Pub Server2 SXEग़ՙପ क़᮱ՙପ ٖ᮱ՙପኞா Dart Packages Flutter Plugin flutter flutter tools flutter test sky_engine dart sdk engine artifacts 构建优化 ྦྷړୗ᧣ᦶL26ܻቘᔄ֒$QGURLG )OXWWHUཛྷୗ ֕አጱฎLGHYLFHORJLSUR[\ )OXWWHUࢫᴚૡ֢ཛྷୗ 双开发模式 iOSVXEP Android(subm) Flutter(ᳳṺ branch&subm) HPEHG JUDGOH ක FlutterIUDPHZRUN ӱ ۓAppIUDPHZRUN flutter_assets ӱۓ vm/isolate_ snapshot_instr/ data ක flutter.jar(libflutter.so) [FUXQ FODQJ [FRGHBEDFNHQGVK ݐJHQHUDWHG[FFRQƉJᯈᗝ snapshot_ assembly.o [FUXQ FF snapshot_ assembly.s JHQBVQDSVKRW JHQBVQDSVKRW ƊXWWHUJUDGOH ݐORFDOSURSHUWLHVᯈᗝ )OXWWHUୌ Flutterۖސ flutter_tools DSSDSN flutter_tools 'DUW'HEXJJHU Ӟ֛۸ۖސӨ᧣ᦶ Androidۖސ gradle DSSDSN DGEORJFDW_ JUHS DGEIRUZDUG 2EVHUYDWRU\_ )OXWWHU3OXJLQ 混合调试 ྦྷړୗႰᦶ᧣ݳ ඪ೮1DWLYHۖސӥ )OXWWHUӾᳵԾᇔ podspec iOSJLWପ ᳳṺL26 aar AndroidJLWପ ᳳṺ$QGURLG ർॠ 1DWLYHཛྷୗ 1DWLYHࢫᴚૡ֢ཛྷୗ ർॠ۱ཛྷୗ MTL打包
- 14.闲⻥鱼iOS⼯工程修改示例例 • 修改⼯工程名为Runner(包括主代码⽂文件夹) • 修改Podfile以处理理Flutter相关逻辑 • 添加Flutter⽬目录,并指定Runner的Debug Config为Flutter/Debug.xcconfig,Release.config为Flutter/ Release.xcconfig • 修改Runner的Build Phases • 添加xcode_backend.sh⽤用于拷⻉贝Flutter.framework,构建App.framework(如果Debug还有snapshot_blob.bin),以及 构建后的thin. • 嵌⼊入App.framework和Flutter.framework(对应代码+引擎) • 嵌⼊入flutter_assets(资源等)
- 15.闲⻥鱼Android⼯工程修改示例例 • 添加包⽂文件夹android/app/src/main以存储GeneratedPluginRegistrant.java • local.properties存储Flutter相关信息 • 引⼊入flutter.gradle • 闲⻥鱼Android⽀支持armeabi • 修改flutter.gradle,将arm64的处理理同arm • 修改libflutter.so⽬目录结构为lib/armeabi/libflutter.so • 修改Android启动Activity启动逻辑以保证多个Launchable-Activity的时候的正确启动。
- 16.Flutter Hybrid栈管理理
- 17.Hybrid栈管理理定义 Page1 Native Page2 Flutter Page3 Flutter Page4 Native Page5 Flutter
- 18.Flutter默认栈管理理 Platform FlutterActivity FlutterView FlutterNativeView Flutter Framework BuildContext Navigator 单实例例 / 多实例例 push() pop() remove() replace() … … route route route … buildPage RoutePageBuilder ҁ:LGJHW҂ history routes ⾃自管理理栈
- 19.两种⽅方案的⽐比较 ⽅方案⼀一 Page1 FlutterActivity shell plt,ui,io,gpu Page2 FlutterActivity shell plt,ui,io,gpu dart vm Page3 FlutterActivity shell plt,ui,io,gpu 更更简单 ⻚页⾯面隔离性好 ⽅方案⼆二 Page1 FlutterActivity FlutterView Page2 FlutterActivity FlutterView Page3 FlutterActivity FlutterView FlutterNativeView Engine 更更快的加载速度 数据多⻚页⾯面复⽤用
- 20.⽅方案⼆二实现 L26׆ᔄࢶ Flutter Framework BuildContext Navigator push() pop() remove() replace() … … route route route … buildPage RoutePageBuilder ҁ:LGJHW҂ history routes ඪ೮OpenURLጱRouter Render FlutterView (CAEAGLLayer) $QGURLG׆ᔄࢶ Render SurfaceView 内部栈跟随 OpenUrl⽀支持 Channel FlutterViewController XFlutterViewController Channel FlutterView XFlutterView 单例例移动 )OXWWHU:UDSSHU9&0RYH9& 6QDSVKRW 6WDFN0DLQWDLQ )OXWWHU:UDSSHU$FWLYLW\ 0RYH9& 6QDSVKRW 6WDFN0DLQWDLQ Activity剥离 转场动画 L26׆ञਫֺ҂ RootVC NativeVC 1(Page1) FlutterWr apperVC1 (Page2) NativeVC (Page3) FlutterWr apperVC4 (Page4) $QGURLG׆ञҁਫֺ҂ RootActiv ity NativeVC 1(Page1) FlutterWrap perActivity1( Page2) NativeVC (Page3) FlutterWrapp erActivity4 (Page4) Native托管栈
- 21.Hybrid⻚页⾯面组件
- 22.Texture⾃自定义视频播放器器 参考:https://www.youtube.com/watch?v=UUfXWzp0-DU
- 23.Texture⾃自定义视频播放器器 使⽤用TextureLayer 参考video_player插件:https://pub.dartlang.org/packages/video_player Flutter->Render(layer_tree) Rasterizer->Draw(layer_tree) LayerTree->Paint() OtherLayer ContainLayer OtherLayer TextureLayer SKCanvas->Draw FlutterFI建_前屏幕ua下x layer_tree,并调用Render渲染 Rasterizer RE统GPUGlK概念不 一n,这里其U就g一个layer_treex 渲染(Paint 并呈v(Present S屏幕上 x过y Layer)reeg一个渲染m,Paint方r将 会递归x遍L每一个节s并e行节s xPaint方r )extureLayerg一个t殊xLayer叶T 节s,调用通过不P平台xUv可以 UvExternal_)exturex渲染 dixLayer最z都g调用(KIAx Canvas来Uv渲染,我Cx External_texture,会封装成一个 (KImage,A给(KCanvas渲染。
- 24.Texture对接⾃自定义视频播放器器 1: 设置⼀一个EventChannel,⽤用于向Flutter通知视频状态变化 2: 设置⼀一个MethodChannel,⽤用于控制video player 3: 设置⼀一个FlutterTexture,⽤用于显示视频帧 4: 从Native播放器器中提取出video frame,贴到FlutterTexture.
- 25.复⽤用Native组件 Platform Channels Flutter Native 注意Layer冲突问题 新建Window或者Activity装载Native组件 开天窗? 还没成功
- 26.• 闲⻥鱼为什什么使⽤用Flutter • Flutter与Native混合开发实践 • Hybrid⼯工程实践 - 研发时 • Hybrid栈管理理 - 运⾏行行时 • 基于Texture对接⾃自定义视频组件 • Flutter通⽤用问题实践 • 详情⻚页⻚页⾯面框架 • 图⽚片缓存注意事项 • 上线效果 • 线上Crash率 • 详情⻚页性能对⽐比 • ⼩小结
- 27.Flutter详情⻚页⻚页⾯面框架
- 28.Server ⻚页⾯面框架 Data 5HTHVW 5HVRQVH DataBindProvider (InheritedWidget) :LGJHW5RRW child children 3DJH&RQWDLQHU 'DWD%LQG hold 'DWD DataBindProvider.of(context).dataBind WidgetsList 7LWOH:LGJHW'HVFULSW:LGJHW,PDJH:LGJHW&RPPHQW:LGJHW&ROOHFW/LVW:LGJHW'DWD7R:LGJHWV3DUVHU 简单的⻚页⾯面: • 动态组装能⼒力力 • InheritedWidget共享数据 • 统⼀一协议(下⻚页详述) 更更复杂的交互⻚页⾯面: • 考虑Redux • Stream
- 29.统⼀一协议 Server JavaDO template Flutter(Dart) 5HT -VRQ(QFRGH 5HV -VRQ'HFRGH 8QLƉHG 3URWRFRO7RRO template template Android 5HT 5HV IOS 5HT 5HV Tree shaking Mirror(反射) 不不⽀支持反射 class PCommentReplyRes { ⽤用⾃自动化代码⼯工具减少Json反射⼯工作量量
- 30.图⽚片缓存
- 31.图⽚片缓存⽅方案 当前默认的图⽚片缓存策略略(官⽅方在优化中): “ class ImageCache Implements a least-recently-used cache of up to 1000 images. The maximum size can be adjusted using [maximumSize]. ” 问题: 内存占⽤用,容易易Crash
- 32.图⽚片缓存⽅方案 ⽅方案1,只有单⻚页⾯面时,简单处理理⽅方案: 1,修改最⼤大缓存图⽚片的数量量,提供⾃自定义Cache的Hook点 class XWidgetsFlutterBinding extends WidgetsFlutterBinding { @override ImageCache createImageCache() { ImageCache cache = new ImageCache(); cache.maximumSize = 110;// the maximum size of cached images. return cache; } } 2,图⽚片尺⼨寸⾃自适应剪裁 • 图⽚片宽度统⼀一泛化为⼀一系列列标准尺⼨寸,如 60, 128, 234 … 640, 720, 960, … • WebP • Quality ⽅方案2,官⽅方正在开发中的基于空间⼤大⼩小的缓存 参考:https://github.com/flutter/flutter/pull/ 17614 set maximumSize(int value) { … } ==》 set maximumSizeBytes(int value) {..} ⽅方案3,增加磁盘缓存: • 共⽤用Native图⽚片库磁盘缓存 优点: • 简化磁盘缓存管理理逻辑,可复⽤用Native逻辑 • 内存缓存还在Flutter端 • 可以为多图传输提供便便利利
- 33.• 闲⻥鱼为什什么使⽤用Flutter • Flutter与Native混合开发实践 • Hybrid⼯工程实践 - 研发时 • Hybrid栈管理理 - 运⾏行行时 • 基于Texture对接⾃自定义视频组件 • Flutter通⽤用问题实践 • 详情⻚页⻚页⾯面框架 • 图⽚片缓存注意事项 • 上线效果 • 线上Crash率 • 详情⻚页性能对⽐比 • ⼩小结
- 34.早期的问题: 内存问题 icu dat问题 视频兼容问题 截图问题 armv7问题 字体问题 … 问题收敛 User Crash率: 百分之⼀一 ⼩小于 万分之⼀一 统计基准⽤用户数: 数百万 达到⽣生产稳定性
- 35.Flutter相关问题处理理思路路 • 构建问题 • 观察⽇日志(打开flutter 插件中的verbose logging) • 调试flutter_tools • 考察flutter.gradle/xcode_backend.sh是否OK • ⻚页⾯面异常或者Crash • 考虑FlutterView/FlutterViewController⽣生命周期是否正常 • 考察产物是否正常 • 符号化后定位问题 • gitter聊天室和github issues
- 36.Flutter相关问题处理理思路路 • 阅读和修改源代码 • flutter插件相关查看https://github.com/flutter/flutter-intellij • flutter框架相关查看flutter仓库下flutter包 • flutter构建相关查看flutter仓库下flutter_tools包 • 平台(iOS/Android)相关,查看engine仓库下flutter>shell • dart编译/runtime相关查看engine仓库下third_party>dart
- 37.Flutter与Native详情⻚页性能对⽐比
- 38.Flutter与Native详情⻚页性能对⽐比 测试场景: 进⼊入宝⻉贝详情⻚页后快速浏览到⻚页⾯面底部,从猜你喜欢进⼊入第⼆二个宝⻉贝,重复 进⾏行行访问10不不同个宝⻉贝详情 测试机型(低端机型为主): Android 4.x, 5.x… iPhone 5c, 6s… 注:⾼高端机型区分不不明显
- 39.Android Xiaomi 5.0.2 Native Flutter CPU 32.32 7.31 dvm memory 228.00 111.86 native memory 134.00 130.80 total memory 362.00 242.57 FPS 22.13 44 SM 17.68 58.29 Lenovo 4.4.4 Lenovo 4.4.4 Native Flutter CPU 16.12 5.43 dvm memory 55.00 90.83 native memory 96.50 91.43 total memory 152.00 182.58 FPS 42.60 32.62 SM 2.3 31.14 Huawei 7.0 Native Flutter CPU 16.74 7.91 dvm memory 395.92 197.08 native memory 143.00 233.24 total memory 539.08 431.05 FPS 38.22 46.2 SM 45.78 58.09 Oppo 4.3 Native Flutter CPU 32.00 26.02 dvm memory 111.71 289.10 native memory 104.00 94.07 total memory 216.14 383.60 FPS 16.97 30.46 SM 4.78 38.56
- 40.iOS iphone 5c 9.0.1 Native Flutter CPU 50.27% 47.3% Memory 149.4 127.28 Traffic total 29349 16757 FPS 39.71 53.08 GPU 4.36% 8.78% iphone 6s 10.3.2 Native Flutter CPU 30.31% 27.42% Memory 247.24 231.66 Traffic total 24868 17686 FPS 47.47 50.08 GPU 21.89% 26.25% 注:以新⽼老老商品详情⻚页为测试对象,相同的研发团队和相似的开发周期。
- 41.⼩小结 效果 成熟度 成本
- 42.技术⽂文章 & FAQ 微信公众号: “闲⻥鱼技术” (Flutter⽂文章定期分享) 基于Google Flutter的移动端跨平台应⽤用实践
- 43.
- 44.
- 45.
- 46.