设为首页 加入收藏

TOP

Flutter 实现原理及在马蜂窝的跨平台开发实践(三)
2019-08-26 06:59:03 】 浏览:97
Tags:Flutter 实现 原理 马蜂窝 跨平台 开发 实践
p.framework : Flutter 工程产物(包含 Flutter 工程的代码,Debug 模式下它是个空壳,代码在 flutter_assets 中)。
  • Flutter.framework: Flutter 引擎库。与编译模式(debug/profile/release)以及 CPU 架构(arm*, i386, x86_64)相匹配。

  • lib.a & .h 头文件: FlutterPlugin 静态库(包含在 iOS 端的实现)。

  • flutter_assets: 包含 Flutter 工程字体,图片等资源。在 Flutter1.2 版本中,被打包到 App.framework 中。

  • Android 集成方案

    Android Nativite 集成是通过 Gradle 远程依赖 Flutter 工程产物的方式完成的,以下是具体的集成流程。

    a.创建 Flutter 标准工程

    $ flutter create flutter_demo

    默认使用 Java 代码,如果增加 Kotlin 支持,使用如下命令:

    $ flutter create -a kotlin flutter_demo

    b. 修改工程的默认配置

    1. 修改 app module 工程的 build.gradle 配置  apply plugin: 'com.android.application' => apply plugin: 'com.android.library',并移除 applicationId 配置

    2. 修改 root 工程的 build.gradle 配置

      在集成过程中 Flutter 依赖了三方 Plugins 后,遇到 Plugins 的代码没有被打进 Library 中的问题。通过以下配置解决(这种方式略显粗暴,后续的优化方案正在调研)。

    subprojects {
       project.buildDir = "${rootProject.buildDir}/app"
    }
    1. app module 增加 maven 打包配置
    2. c. 生成 Android Flutter 产物
    $ cd android
    $ ./gradlew uploadArchives

    官方默认的构建脚本在 Flutter 1.0.0 版本存在 Bug——最终的产物中会缺少 flutter_shared/icudtl.dat 文件,导致 App Crash。目前的解决方式是将这个文件复制到工程的 assets 下( 在 Flutter 最新 1.2.1 版本中这个 Bug 已被修复,但是 1.2.1 版本又出现了一个 UI 渲染的问题,所以只能继续使用 1.0.0 版本)。

    d. Android Native 平台工程集成,增加下面依赖配置即可,不会影响 Native 平台开发的同学

    implementation 'com.mfw.app:MerchantFlutter:0.0.5-beta'

    Flutter 和 iOS、Android  的交互

    使用平台通道(Platform Channels)在 Flutter 工程和宿主(Native 工程)之间传递消息,主要是通过 MethodChannel 进行方法的调用,如下图所示:

    图 12 :Flutter 与 iOS、Android 交互

     

    为了确保用户界面不会挂起,消息和响应是异步传递的,需要用 async 修饰方法,await 修饰调用语句。Flutter 工程和宿主工程通过在 Channel 构造函数中传递 Channel 名称进行关联。单个应用中使用的所有 Channel 名称必须是唯一的; 可以在 Channel 名称前加一个唯一的「域名前缀」。

    Flutter 与  Native 性能对比

    我们分别使用 Native 和 Flutter 开发了两个列表页,以下是页面效果和性能对比:

    iOS 对比(机型 6P 系统 10.3.3):

    Flutter 页面:

    iOS Native 页面:

    可以看到,从使用和直观感受都没有太大的差别。于是我们采集了一些其他方面的数据。

    Flutter 页面:

    iOS Native 页面:

    另外我们还对比了商家端接入 Flutter 前后包体积的大小:39Mb →  44MB

    在 iOS 机型上,流畅度上没有什么差异。从数值上来看,Flutter 在 内存跟 GPU/CPU 使用率上比原生略高。Demo 中并没有对 Flutter 做更多的优化,可以看出 Flutter 整体来说还是可以做出接近于原生的页面。

    下面是 Flutter 与 Android 的性能对比。

    Flutter 页面:

    Android Native 页面:

    从以上两张对比图可以看出,不考虑其他因素,单纯从性能角度来说,原生要优于 Flutter,但是差距并不大,而且 Flutter 具有的跨平台开发和热重载等特点极大地节省了开发效率。并且,未来的热修复特性更是值得期待。

     

    混合栈管理

    首先先介绍下 Flutter 路由的管理:

    • Flutter 管理页面有两个概念:Route 和 Navigator。

    • Navigator 是一个路由管理的 Widget(Flutter 中万物皆 Widget),它通过一个栈来管理一个路由 Widget 集合。通常当前屏幕显示的页面就是栈顶的路由。

    • 路由 (Route) 在移动开发中通常指页面(Page),这跟 web 开发中单页应用的 Route 概念意义是相同的,Route 在 Android 中通常指一个 Activity,在 iOS 中指一个 ViewController。所谓路由管理,就是管理页面之间如何跳转,通常也可被称为导航管理。这和原生开发类似,无论是 Android 还是 iOS,导航管理都会维护一个路由栈,路由入栈 (push) 操作对应打开一个新页面,路由出栈 (pop) 操作对应页面关闭操作,而路由管理主要是指如何来管理路由栈。

    图 14 :Flutter 路由管理

     

    如果是纯 Flutter 工程,页面栈无需我们进行管理,但是引入到 Native 工程内,就需要考虑如何管理混合栈。并且需要解决以下几个问题:

    1. 保证 Flutter 页面与 Native 页面之间的跳转从用户体验上没有任何差异

    2. 页面资源化(马蜂窝特有的业务逻辑)

    3. 保证生命周期完整性,处理相关打点事件上报

    4. 资源性能问题

    参考了业界内的解决方法,以及项目自身的实际场景,我们选择类似于 H5 在 Navite 中嵌入的方式,统一通过 openURL 跳转到一个 Native 页面(FlutterContainerVC),Native 页面通过 addChildViewController 方式添加 FlutterViewController(负责 Flutter 页面渲染),同时通过 channel 同步 Native 页面与 Flutter 页面。

    • 每一次的 push/pop 由 Native 发起,同时通过 channel 保持 Native 与 Flutter 页面同步——在 Native 中跳转 Flutter 页面与跳转原生无差异

    • 一个 Flutter 页面对应一个 Native 页面(FlutterContainerVC)——解决页面资源化

    • FlutterContainerVC 通过 addChildViewController 对单例 FlutterViewController

    首页 上一页 1 2 3 4 下一页 尾页 3/4/4
    】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
    上一篇关于OC中的几种延迟执行方式 下一篇电商 APP 下单页(俗称车2) 业务..

    最新文章

    热门文章

    Hot 文章

    Python

    C 语言

    C++基础

    大数据基础

    linux编程基础

    C/C++面试题目