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目錄顯示出來了
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容