针对iOS在Mac平台上编译Flutter引擎
针对iOS编译Flutter引擎
现有iOS项目中以module的方式接入Flutter,并且从原生页面跳转进Flutter的时候,会发现内存飙升,并且在退出FlutterViewController之后,内存并没有销毁;就会导致原本手机内存就吃紧的情况下,造成app的闪退。
虽然可以通过单引擎单FlutterViewController的方式来抵消部分内存消耗,但是使用单引擎单FlutterViewController来跳转Flutter制定页面的时候就显得不方便,并且FlutterViewController的setInitialRoute方法会失效,导致使用setInitialRoute来跳转指定Widget页面的时候,window.defaultRouteName收到的总是 “/”,得不到设定的数据。
之所以使用单引擎单FlutterViewController的方式会出现这种问题,是因为FlutterEngin在启动的时候就默认加载了Widget,导致设置setInitialRoute的时候不生效。
为了探究这个问题,就需要拿到flutter有关engin的源码,看了源码后,自然就会有修改源码的冲动;修改后如何进行编译呢?
接下来将会讲述Flutter.framework的编译配置过程
1、配置depot_tools
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
配置depot_tools环境变量
export PATH="$PATH:/path/to/depot_tools"
如果下载过程中出现443: Operation timed out,
最后在使用的终端中设置临时端口:
export http_proxy=http://127.0.0.1:1080 //这里的端口号一定要与你使用的的dai-li端口一致
export https_proxy=http://127.0.0.1:1080 //这里的端口号一定要与你使用的的dai-li端口一致
设置完之后,就能正常拉取depot_tools代码。
2、获取flutter的engine源码和编译需要的第三方库
cd进去桌面(Desktop)或者别的目录,创建一个flutter_engine目录
cd ~/Desktop
mkdir flutter_engine
cd flutter_engine
在flutter_engine目录下创建一个**.gclient**,然后在.gclient输入以下内容:
solutions = [
{
"managed": False,
"name": "src/flutter",
"url": "https://github.com/LVHAI/engine.git@b863200c37df4ed378042de11c4e9ff34e4e58c9",//此处可以修改为个人fork的flutter-engin地址,或者flutter-engin的github地址
"custom_deps": {},
"deps_file": "DEPS",
"safesync_url": "",
},
]
上述中的 “url” 为flutetr-engine的地址,用 @ 符号进行分割的两部分分别为:
https://github.com/LVHAI/engine.git:这部分代表flutetr-engine引擎地址
b863200c37df4ed378042de11c4e9ff34e4e58c9:这部分代表你使用的flutter引擎版本号,路径为xxx/flutter/bin/internal/engine.version
接下来进入到创建的 flutter_engine目录: 执行gclient sync命令
gclient sync 查看不到执行过程
如果想查看gclient sync的执行过程,可以在terminal键入:
gclient sync --verbose 可以查看到命令的执行过程
接下来只需耐性等待执行完成。
出现此种情况就表示成功了
这一步主要是为了下载编译需要依赖的一些第三方文件:
3、开始进行编译
首先进入到src目录下
cd ~/Desktop/flutter_engine/src
先来看一段github上面Wiki关于编译的描述:
These steps build the engine used by flutter run for iOS devices.
Run the following steps, from the src directory created in the steps above:
git pull upstream master in src/flutter to update the Flutter Engine repo.
gclient sync to update dependencies.
./flutter/tools/gn --ios --unoptimized to prepare build files for device-side executables (or --ios --simulator --unoptimized for simulator).
This also produces an Xcode project for working with the engine source code at out/ios_debug_unopt
For a discussion on the various flags and modes, see Flutter's modes.
./flutter/tools/gn --unoptimized to prepare the build files for host-side executables.
ninja -C out/ios_debug_unopt && ninja -C out/host_debug_unopt to build all artifacts (use out/ios_debug_sim_unopt for Simulator).
生成针对模拟器的Flutter.framework
1、生成针对模拟器的未优化版本:
./flutter/tools/gn --ios --simulator --unoptimized
ninja -C out/ios_debug_sim_unopt //ios_debug_sim_unopt,为上一步生成的文件夹名称
2、生成针对模拟器的优化版本:
./flutter/tools/gn --ios --simulator
ninja -C out/ios_debug_sim_unopt //ios_debug_sim_unopt,为上一步生成的文件夹名称
在执行完成 ./flutter/tools/gn --ios --simulator之后,会在src目录下面看到多出来一个out文件目录,out里面存放的就是刚生成的针对模拟器版本的ios_debug_sim_unopt文件,有了这个文件,才能进行下一步的编译操作;
ninja -C out/ios_debug_sim_unopt 这一步执行完,就会生成Flutter.framework,把个人生成的Flutter.framework文件放到项目工程中去替换之前的flutter文件,或者去flutter的安装目录中替换成字节生成的Flutter.framework;
可以通过lipo -info查看Flutter.framework支持的型号:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xQlFWA0T-1585102634421)(./lipo_info.png)]
生成针对手机的版本
生成能在手机上运行的framework的时候,也分为优化版和未优化版,仅仅是在参数中有没有 –unoptimized这个参数。
./flutter/tools/gn --ios --unoptimized --runtime-mode=release //此处的--unoptimized可以删除掉
ninja -C out/ios_xxx_unopt //out后面的文件名称为上一步生成的文件名
有关–runtime-mode的模式,可以分为四种:
Debug
Release
Profile
Headless test
要选择那种方式编译,可自行选择。
后续有空将会说明,FlutterViewController、FlutterEngin、FlutterMethodChannel、FlutterEventChannel以及Flutter的集中decodec存在关系。