1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/CarGuo-GSYFlutterBook

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Flutter-N19.md 11 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 10.03.2025 00:06 5767d61

Простое руководство по Flutter 3.7: более гибкая поддержка переменных сборки

Сегодня мы поговорим о простом, но важном изменении в Flutter 3.7. В разделе с изменениями release-notes есть одно изменение, которое не было отмечено в официальном объявлении, но для меня это очень полезная возможность:

  • [flutter_tools] Исправление, чтобы значение, установленное с помощью --dart-define-from-file, могло передаваться Gradle'у @blendthink в https://github.com/flutter/flutter/pull/114297

Наткнулся на эту небольшую функцию случайно, и она стала приятной неожиданностью.

Dart

До версии 3.7, если нам требовалось динамически добавлять переменные во время компиляции в Flutter, мы использовали --dart-define. Например:

flutter run --dart-define=APP_CHANNEL=Официальный

const APP_CHANNEL = String.fromEnvironment('APP_CHANNEL');

Мы можем указывать переменную через командную строку с помощью --dart-define, а затем читаем её внутри Flutter с помощью String.fromEnvironment. Это работает хорошо в большинстве случаев, однако:

  • При необходимости определения нескольких переменных команда становится длинной и трудно поддерживать.

  • Для смешанного развития, переменные также должны быть синхронизированы со значениями конфигураций в проектах на других языках, что усложняет процесс.

До этого момента, для синхронизации значений между различными проектами на других языках, я использовал пользовательские скрипты:- На Android использую gradle-скрипт, который читает конфигурацию из файла, аналогично тому, как это делается в RN с помощью dotenv, и модифицирую project.env.

  • На iOS использую чтение конфигурации из скрипта и системный PlistBuddy для внесения изменений в параметры при компиляции.

Начиная с Flutter 3.7, всё стало проще благодаря возможности использования --dart-define-from-file:

flutter run --dart-define-from-file=config.json

////// config.json ////// 
{
  "TEST_KEY1": "test key 1",
  "TEST_KEY2": "test key 2"
}

Используя ту же идею dart define, теперь --dart-define-from-file позволяет считывать конфигурацию из JSON-файла, преобразовывать её в Map, а затем использовать её в окружении. Таким образом, вы можете читать параметры через String.fromEnvironment в Dart, а использование JSON-конфигурации улучшает управление множеством переменных.

И это всё? Очевидно, что нет. Ранее мы говорили о синхронной модификации конфигураций различных нативных проектов, а в Flutter 3.7 официальная поддержка была внедрена.

Android

Сначала рассмотрим Android. Мы можем определить переменную dartEnvVar в файле app/build.gradle, которая используется для чтения параметров, внедренных в project из ранее упомянутого JSON файла.

Затем вы можете использовать dartEnvVar для прямого обращения к соответствующим параметрам в файле app/build.gradle. Например, можно определить resValue, как показано ниже, где dartEnvVar успешно считывает параметры из JSON-файла во время компиляции.| | | | ------------------------------------------------------ | ------------------------------------------------------ |

Как показано на следующем рисунке, после того как вы прочитаете конфигурацию окружения Dart через project, вы можете определять resValue для изменения файла AndroidManifest, а также встраивать его в BuildConfig для использования в нативном коде. Для конфигурации вам потребуется поддерживать лишь один JSON файл.

image-20230208182506190

А как это реализовано? Вкратце, в скрипте flutter/packages/flutter_tools/lib/src/build_info.dart ранее считанный JSON файл преобразуется в объект dartDefineConfigJsonMap, который затем становится списком параметров Gradle, используемых при выполнении задачи сборки assembleTask.

Здесь важно отметить, что ключи, которые вы определяете, не должны конфликтовать с зарезервированными ключами, такими как dart-obfuscation.

При выполнении команды будет использоваться следующий формат: -PTEST_KEY1=test key 1 -PTEST_KEY2=test key 2.

iOS

На платформе iOS процесс аналогичен. Вам просто нужно определить ключи и значения в файле Info.plist. Во время компиляции с помощью --dart-define-from-file, генерируются соответствующие конфигурационные данные xcconfig.

В каталоге ios/Flutter создаются два игнорируемых файла во время компиляции — flutter_export_environment.sh и Generated.xcconfig. После компиляции эти файлы содержат соответствующие ключи и значения.

| | | | ------------------------------------------------------ | ------------------------------------------------------- |> Здесь стоит обратить внимание, что в iOS формат xcconfig считает // как разделитель комментариев, то есть всё после // игнорируется. Это значит, что вы не сможете передать URL, такой как https://xxxx, так как всё после // будет проигнорировано.

Конечно, если вам нужны значения по умолчанию, вы можете настроить это в файлах Debug.xcconfig и Release.xcconfig в директории ios/Flutter.

Как и в случае с Android, при сборке iOS проекта аргумент --dart-define-from-file преобразуется в параметры xcconfig, обеспечивая использование одной конфигурации переменных для Dart и iOS.

В заключение

Использование и реализация --dart-define-from-file не являются сложными. До его появления мы могли использовать некоторые другие методы для достижения аналогичного эффекта.

Однако появление команды --dart-define-from-file значительно упростило процесс сборки, сделав цепочку динамической конфигурации более гибкой и надёжной. Поэтому она является одним из самых полезных и легко пропущенных обновлений в версии 3.7.Не могу не отметить, что версия Flutter 3.7 принесла нам множество приятных сюрпризов, таких как toImageSync и фоновый изолят, которые были долгожданными функциями. Поддержка подобных возможностей, как --dart-define-from-file, также продолжает совершенствовать опыт разработки в Flutter.Наконец, начиная с небольших обновлений после версии 3.7, можно выделить две особенности:

    1. У Impeller действительно ещё много проблем;
    1. Impeller действительно уже здесь, даже если это предварительная функциональность, её исправления включены в основную ветку.

image

Жду, когда следующий выпуск Impeller порадует нас ещё большими преимуществами.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/CarGuo-GSYFlutterBook.git
git@api.gitlife.ru:oschina-mirror/CarGuo-GSYFlutterBook.git
oschina-mirror
CarGuo-GSYFlutterBook
CarGuo-GSYFlutterBook
master