Flutter Engine

574 阅读1分钟

1、下载引擎

1.1、查看引擎信息

1.1.1、查看当前引擎版本号

  • 终端指令:% flutter doctor -v

    image.png

1.1.2、查看并切换引擎版本

  • % flutter channel

    image.png

  • flutter channel后直接加版本类型可以切换过去:flutter channel master

1.1.3、引擎版本完整编号

  • % cat $FLUTTER/bin/internal/engine.version

    image.png

1.1.4、"科学🪜"下载Engine代码

2、GN构建文件

  • ⽣成Ninja构建⽂件的元构建系统,最后我们还是⽤Ninja编译!

2.1、首先找到GN文件

image.png

2.2、构建iOS设备使⽤的引擎

  • 先cd到gn所在文件夹
    • 真机debug版本:./gn --ios --unoptimized
    • 真机release版本(⽇常开发使⽤,如果我们要⾃定义引擎):./gn --ios --unoptimized --runtime-mode=release
    • 模拟器版本:./gn --ios --simulator --unoptimized
    • 主机端(Mac)构建:./gn --unoptimized
  • 可能遇到报错,查看偏好设置中是否程序被安全性与隐私拦截

2.3、各版本构建完成

  • out目录产生对应工程 image.png

3、Ninja编译文件(很耗时)

  • 编译GN构建的文件,可以同时编译
    • 先cd到out目录再执行下边命令(下边为4种同时进行编译)
    • ninja -C host_debug_unopt && ninja -C ios_debug_sim_unopt && ninja -C ios_debug_unopt && ninja -C ios_release_unopt
    • 找不到ninja的可以先安装ninja:% brew install ninja
    • 也可能遇到报错,查看是否程序被安全性与隐私拦截
    • 修改引擎代码内容后也需要再执行该命令,然后才能看到修改效果 image.png

4、配置项目代码

4.1、Generated.xcconfig⽂件中添加环境变量

  • 运行Flutter文件中的Runner.xcworkspace文件找到Generated.xcconfig⽂件,在⾥⾯添加两个环境变量,将引擎文件与该文件关联
    FLUTTER_ENGINE=你存放引擎代码的路径/engine/src 
    #使⽤的引擎对应版本(这⾥是iOS-debug模式下-模拟器的版本) 
    LOCAL_ENGINE=ios_debug_sim_unopt
    
    • FLUTTER_ENGINE:引擎路径
    • LOCAL_ENGINE:GN编译文件 image.png

4.2、检查⼆进制是否含有调试信息

  • lipo命令
    #可以查看包含的架构 
    $lipo -info xxx 
    
    #拆分架构 
    $lipo xxx -thin armv7 -output armv7_xxx 
    
    #合并多架构 
    $lipo -create xxx.a xxx.a -output xxx.a
    

4.3、LLDB检查是否含有调试信息

$lldb --file Flutter_arm64 
(lldb) target create "Flutter_arm64" 
Current executable set to 'Flutter_arm64' (arm64). 
(lldb) script lldb.target.module['Flutter_arm64'].GetNumCompileUnits() 
1
(lldb)

4.4、使⽤python列出模块的所有编译单元的完整路径

(lldb) target create "Flutter_arm64" 
Current executable set to 'Flutter_arm64' (arm64). 
(lldb) script 
Python Interactive Interpreter. To exit, type 'quit()''exit()' or Ctrl-D.
>>> m = lldb.target.module['Flutter_arm64'] 
>>> for i in range(m.GetNumCompileUnits()): 
... cu = m.GetCompileUnitAtIndex(i).file.fullpath 
... print(cu) 
... 
None 
>>>

5、底层实现内容

5.1、channel

  • 将channelName、消息管理者对象binaryMessengercodec(单例、隐式)retain
  • setMethodCallHandler:(FlutterMethodCallHandler *) image.png

5.2、codec编解码器

  • 其实是一种协议
  • 内部FlutterStandardReadWriter实现read和write方法

6、热重载挂载

  • 通过服务端执行来运行其他项目(需要下载服务端开源代码) image.png

6.1、热重载运行流程

  • Dart代码 --> Dart Server--> Dart虚拟机 --> iOS客户端(通过RPC协议通讯渲染引擎Flutter.framework) image.png

备注:

下断点、跟方法传递

  • br set -n "touchesBegan:":跟touchesBegan方法,可跨工程,执行"c"命令进行下一步

超过3个选项时Switch比if、else效率要高