Новости
07.07.2024
СБОРКА ПРИЛОЖЕНИЯ. РАБОТА С ФАЙЛАМИ И КАТАЛОГАМИ
В данной главе мы рассмотрим флаги сборки приложений и то, как их применять на практике. Кроме того, поговорим о конфигурации приложения путем передачи необходимых данных через терминал в момент его запуска. Отдельно рассмотрим механизмы Dart для работы с файлами и каталогами.
Файлы могут выступать в различном амплуа: от конфигурационных до хранилищ. Например, в конфигурационные выносится информация, которую пользователь может изменять в настройках приложения и которая влияет на логику его работы. Это делается для большей гибкости, поскольку хранение такой информации в самом коде программного продукта подразумевает, что при малейшем ее изменении необходимо заново выполнять сборку (компиляцию) программы. А в качестве примера использования файлов как хранилищ реализуем простую базу данных на основе односвязного списка.
Сборка приложения
Для сборки приложений используется команда dart compile, имеющая ряд конфигурационных флагов, отвечающих за режим компиляции [11] (табл. 5.1).
В данной таблице под целевой платформой понимается та, на которой производится компиляция приложения (Windows, Linux и т. д.). Если вам нужен полностью автономный файл приложения, то используйте флаг exe. Если важна скорость и оптимизация — поможет jit-snapshot. Если хотите, чтобы приложение запустилось на любой платформе, — используйте kernel.
У каждого из имеющихся флагов есть свои плюсы и минусы. Например, exe и aot-snapshot не поддерживают библиотеки dart:mirrors и dart:developer. Флаг kernel не предоставляет стабильного API, поэтому нет гарантии, что при сборке приложения на одной версии Dart оно запустится на другой. Для запуска файла, скомпилированного с флагом aot-snapshot, требуется утилита dartaotruntime, предоставляющая среду выполнения Dart. А если вы хотите запустить файлы, скомпилированные с флагом jit-snapshot или kernel, то требуется наличие установленного на платформе Dart SDK.
Далее рассмотрим, как осуществлять сборку приложения и его запуск (за исключением использования флага js). И начнем с создания нового консольного приложения my_app, в котором не надо ничего добавлять или удалять.
Флаг exe
Откройте терминал Terminal New Terminal и введите команду:
dart compile exe bin\my_app.dart
в которой после флага сборки указывается путь до компилируемого файла. (Будьте внимательны: если у вас Mac или Linux, то используйте другой формат пути — bin/my_app.dart.)
В каталоге bin проекта my_app должен появиться скомпилированный файл с расширением .exe (рис. 5.1).
Вне зависимости от того, какая у вас операционная система, файл будет иметь такое расширение. Это не значит, что он собран только для Windows! У каждого флага компиляции свое выходное расширение, в данном случае — exe.
Если необходимо поменять путь, указать, куда переместить собранное приложение или имя компилируемого файла, то воспользуйтесь дополнительным параметром -о:
dart compile exe bin\my_app.dart -o bin\new_app
или
dart compile exe bin\my_app.dart -o bin\new_app.exe
Для запуска приложения, скомпилированного таким образом, достаточно указать в терминале путь до него и нажать Enter (рис. 5.2).
Флаг aot-snapshot
Удалите скомпилированные ранее файлы из каталога bin, после чего введите в терминале следующую команду:
dart compile aot-snapshot bin\my_app.dart
Как и с флагом exe, можно использовать дополнительный параметр -о, чтобы указать, куда и с каким именем поместить скомпилированный файл:
dart compile aot-snapshot bin\my_app.dart -o C:\code\new_app.aot
Для запуска приложения, скомпилированного с таким флагом, понадобится утилита dartaotruntime, предоставляющая среду выполнения Dart. Еще в самом начале после установки Dart SDK мы прописывали необходимые пути в переменной среды path, поэтому просто начните команду со слова dartaotruntime (рис. 5.3):
dartaotruntime bin\my_app.aot
Флаг jit-snapshot
Данный флаг не поддерживает параметр -о, так как в момент компиляции осуществляется обучающий запуск приложения и то, насколько качественно он будет выполнен, отразится на итоговой оптимизации приложения. В некоторых случаях удается достичь значительного прироста быстродействия.
Удалите скомпилированные ранее файлы из каталога bin и введите следующую команду (рис. 5.4):
dart compile jit-snapshot bin\my_app.dart
В каталоге bin проекта my_app должен появиться скомпилированный файл с расширением .jit (рис. 5.5).
Для запуска приложения, скомпилированного с таким флагом, понадобится установленный на целевой платформе Dart SDK. В нашем случае все уже установлено и настроено, поэтому мы можем сразу перейти к последнему шагу. Для этого введите в терминале следующую команду (рис. 5.6):
dart run bin\my_app.jit
Флаг kernel
Использование этого флага для компиляции ничем не отличается от флага exe:
dart compile kernel bin\my_app.dart
или
dart compile kernel bin\my_app.dart -o C:\code\new_app
После передачи полученного файла третьей стороне убедитесь, что там имеется установленный Dart SDK (рис. 5.7):
dart run bin\my_app.dill
Конфигурация запускаемого приложения
Бывают случаи, когда в момент старта приложения ему необходимо передать какой-то набор параметров (данных) для последующей корректной работы. В принципе, нет четкого стандарта, как эти данные окажутся в программе: считаются ли с конфигурационного файла, с базы данных либо передадутся напрямую с терминала в команде запуска.
Поскольку работе с файлами посвящены следующие разделы главы, здесь мы сосредоточимся на последнем варианте и рассмотрим, зачем в главной функции main такой входной аргумент, как List arguments.
Для начала немного перепишем тело функции main в файле my_app.dart каталога bin:
import 'package:my_app/my_app.dart' as my_app;
void main(List<String> arguments) {
print(arguments);
print('Hello world: ${my_app.calculate()}!');
}
Теперь скомпилируйте приложение с флагом exe и запустите его следующим образом (рис. 5.8):
bin\my_app.exe
bin\my_app.exe -a 34 -b -_- -c hellow world!
Обратите внимание, что все данные, которые были указаны в качестве параметров (-имяПараметра) приложения при запуске, и следующие за ними данные были переданы на вход функции main в списке arguments.
Немного перепишем код и сложим два числа, подающихся при запуске приложения:
void main(List<String> arguments) {
print(arguments);
var a = int.tryParse(arguments[0]);
var b = int.tryParse(arguments[1]);
if (a = = null || b = = null) {
print('Invalid input');
return;
}
print('a + b = ${a + b}');
}
Снова скомпилируйте приложение и запустите его, используя следующие команды (рис. 5.9).
Но если на вход приложения не подать ни одного или одно значение, то его работа сразу завершится исключением. Поэтому при взаимодействии с позиционными аргументами нужно учитывать множество факторов, особенно когда их огромное количество. Из-за этого и используются флаги и параметры (свойства — флаг с данными после него), которые позволяют понять, есть в передаваемых на вход данных нужные значения или нет.
Не будем изобретать велосипед и воспользуемся уже готовым пакетом: args (https://pub.dev/packages/args), позволяющим задать имена параметров и флагов для их поиска и извлечения данных, а также использования значений по умолчанию, если их не передали в момент запуска приложения.
Откройте файл pubspec.yaml и добавьте в раздел с зависимостями пакет args:
# Add regular dependencies here.
dependencies:
args: ^2.4.2
# path: ^1.8.0
Вернемся к файлу my_app.dart из каталога bin и внесем в него следующие изменения:
import 'package:args/args.dart';
void main(List<String> arguments) {
var parser = ArgParser();
parser.addOption( // добавляем параметр/свойство в парсер
'firts', // по данному ключу будет осуществляться поиск данных
abbr: 'a', // имя свойства при его указании в момент запуска
help: 'First number',
defaultsTo: '1', // значение по умолчанию
);
parser.addOption(
'second',
abbr: 'b',
help: 'Second number',
defaultsTo: '5',
);
parser.addFlag( // добавляем флаг в парсер
'subtract',
abbr: 's',
help: 'Subtract mode',
defaultsTo: false,
);
var args = parser.parse(arguments);
print(arguments);
var a = int.parse(args['firts']);
var b = int.parse(args['second']);
if (args['subtract']){
print('a - b = ${a - b}');
}else{
print('a + b = ${a + b}');
}
}
Скомпилируйте приложение и запустите его с различными параметрами (рис. 5.10). Обратите внимание: вне зависимости от количества передаваемых на старте приложения значений оно работает нормально. Это связано с тем, что для каждого свойства и флага было указано значение по умолчанию.
Лауреат премии Правительства Санкт-Петербурга в области научно-педагогической деятельности в 2021 и 2023 г.
Более подробно с книгой можно ознакомиться на сайте издательства
Комментарии: 0
Пока нет комментариев