Flutter -- 18.项目代码关联渲染引擎

1.这里创建一个Flutter项目(App)

  • 使用Xcode打开其中的iOS工程
  • 打开Generated.xcconfig添加环境变量
//添加环境变量
//1.引擎代码的src路径
FLUTTER_ENGINE=/Users/mac/Desktop/Flutter-Engine/engine_download/src
//2.使用引擎对应版本,模拟器版本
LOCAL_ENGINE=ios_debug_sim_unopt
  • Command+R运行该iOS项目

2. 工程关联过程(Xcode->Dart)

  • iOS脚本配置在Target->Build Phases->Run Script
/bin/sh "$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh" build
  • 进入$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh($FLUTTER_ROOT为FlutterSDK位置)
  • xcode_backend.sh
#!/usr/bin/env bash
# Copyright 2014 The Flutter Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# exit on error, or usage of unset var
set -euo pipefail

# Needed because if it is set, cd may print the path it changed to.
unset CDPATH

function follow_links() (
  cd -P "$(dirname -- "$1")"
  file="$PWD/$(basename -- "$1")"
  while [[ -h "$file" ]]; do
    cd -P "$(dirname -- "$file")"
    file="$(readlink -- "$file")"
    cd -P "$(dirname -- "$file")"
    file="$PWD/$(basename -- "$file")"
  done
  echo "$file"
)

PROG_NAME="$(follow_links "${BASH_SOURCE[0]}")"
BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
FLUTTER_ROOT="$BIN_DIR/../../.."
DART="$FLUTTER_ROOT/bin/dart"

"$DART" "$BIN_DIR/xcode_backend.dart" "$@"
  • xcode_backend.sh没有使用到Generated.xcconfig文件中的环境变量
  • xcode工程执行了这个脚本后,然后执行到了xcode_backend.dart这个文件

  • 进入xcode_backend.dart文件,之前的环境变量在这个文件使用到了。具体代码太长就没有贴出来

3.证明运行的iOS项目与我自己的渲染引擎已经关联

  • 1.在运行中的项目下一个断点touchesBegan:withEvent:
br set -n "touchesBegan:withEvent:"
  • 2.点击屏幕,过掉一些UI相关的断点后,进入FlutterViewController.mm断点
    touchBegan_breakpoint.png
  • 3.在touchesBegan添加打印语句
- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
    NSLog(@"123");
  [self dispatchTouches:touches pointerDataChangeOverride:nullptr event:event];
}
  • 4.通过Command+j查看不到FlutterViewController.mm文件所在位置
  • 5.猜测FlutterViewController.mm是在Flutter引擎代码里,打开ios_debug_sim_unopt工程查看
    flutter_engin_code.png

1.这里可以清晰的看到,刚才写的打印语句在Flutter引擎代码里面
2.此时Xcode工程和FLutter渲染引擎已经关联起来了

4.为什么点击屏幕控制台不执行打印语句?

  • 原因其实很简单,当我们引擎改了代码,需要使用ninja去编译一次
  • Xcode工程使用的是Flutter.framework,因此修改后必须编译一次更新Flutter.framework
mac@mac out % ninja -C host_debug_unopt && ninja -C ios_debug_sim_unopt
ninja: Entering directory `host_debug_unopt'
ninja: no work to do.
ninja: Entering directory `ios_debug_sim_unopt'
[16/16] STAMP obj/default.stamp
  • Xcode工程停掉,再运行
  • 点击模拟器屏幕,此时打印输出正常

5.原理剖析

  • 此时查看FlutterViewController.mm文件所在位置
  • 你会惊讶的发现FlutterViewController.mm文件不在ios_debug_sim_unopt目录下
  • 路径为/src/flutter/shell/platform/darwin/ios/framework/Source
  • 源码存放的位置并不在编译后的文件内,而是在引擎源码的其它目录下

    总结
  • 因此并不是每编译一次模拟器/真机(release/debug),就会重新生成一份源码
  • 它是根据同一份源码编译出不同的产物

6.md5检查Flutter.framework

  • 比对4次Flutter.framework的md5值(2次自定义版本,2次发布版本)


    Product_flutterframework.png
  • 1.Generated.xcconfig添加环境变量,使用自定义引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 417ded8d1d0c7999c680ac31a9aae3f3
  • 2.Generated.xcconfig注释环境变量+编译,使用发布版本引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 15efda2506d5e9c6904ceb1837b26124
  • 3.Generated.xcconfig添加环境变量,使用自定义引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 0e4c584880f59b3b35ec48d68f820c93
  • 4.Generated.xcconfig注释环境变量+编译,使用发布版本引擎
mac@mac Flutter.framework % md5 Flutter
MD5 (Flutter) = 6735d5613997e710ed37b9a27aab8bfc
  • 可以看出,每一次的md5值是不一样的
  • 工程每次编译在生成Flutter.framework都是不一样的(无论是发布版本还是自定义版本)
  • 工程在每次编译生成Flutter.framework的时候还要加入内容的,因此多次是不一样的

7.Xcode13不显示Product目录

  • 打开项目project.pbxproj
  • 搜索productRefGroup
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146E51CF9000F007C117D /* Products */;
  • productRefGroup的值换成mainGroup的(这里的我已经修改好了)
  • Command+s保存后退出,就会发现工程中的Product目录显示出来了

你可能感兴趣的:(Flutter -- 18.项目代码关联渲染引擎)