Dart — язык со строгой типизацией и полной null-безопасностью, а Flutter — набор библиотек и инструментов, который собирает один и тот же интерфейс под Linux, Android и iOS. Для Linux-разработчика это способ делать десктопные утилиты без отдельного слоя под каждую платформу. Ниже — установка, структура проекта, сборка под Linux и мобильные, работа с платформенным кодом и типичные ошибки.
Что даёт связка Dart и Flutter
Dart компилируется в машинный код для десктопа и мобильных, а в вебе — в JavaScript или WebAssembly. Flutter рисует интерфейс собственным движком, поэтому виджеты выглядят одинаково на разных системах. Плата — размер приложения и следование виджетной модели.
- горячая перезагрузка ускоряет итерации;
- один код интерфейса и бизнес-логики для нескольких платформ;
- богатый набор виджетов и готовых пакетов.
Для системных утилит, которым нужен только терминал, Flutter избыточен. Но для приложения с формами, таблицами и настройками он экономит время.
Установка инструментов
На Linux проще всего поставить Flutter через snap: пакет включает SDK Dart и сам фреймворк. Альтернатива — клонировать стабильную ветку вручную и добавить bin в PATH. Для сборки десктопа нужны компилятор, CMake, Ninja и заголовки GTK.
sudo apt install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev
sudo snap install flutter --classic
flutter config --enable-linux-desktop
flutter doctor -v
flutter doctor показывает, каких компонентов не хватает. Для Android нужен SDK, для iOS — macOS с Xcode. Часть предупреждений превращается в ошибки релизной сборки.
Структура проекта
Новый проект создают с явным списком платформ, чтобы не тащить лишние каталоги. Каталог lib содержит код Dart, linux и android — платформенные обёртки, а test — тесты. Зависимости описываются в pubspec.yaml и фиксируются в pubspec.lock.
flutter create --org su.example --platforms=linux,android,ios myapp
cd myapp
flutter pub add http
flutter devices
Файл pubspec.yaml задаёт имя пакета, версию, окружение SDK и зависимости. Слишком широкий диапазон версий приносит несовместимые обновления, слишком узкий затрудняет исправления.
name: myapp
environment:
sdk: '>=3.5.0 <4.0.0'
dependencies:
flutter:
sdk: flutter
http: ^1.2.0
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
Версии — ориентир: актуальные значения смотрите на pub.dev.
Первый экран
Точка входа вызывает runApp, а интерфейс собирается из виджетов. Ниже минимальное приложение со счётчиком: оно показывает состояние, обработку нажатия и перерисовку через setState. Для крупных проектов состояние выносят в отдельные классы или пакеты, но начинать удобнее с простого.
import 'package:flutter/material.dart';
void main() => runApp(const MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
title: 'MyApp',
home: const CounterPage(),
);
}
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() => _CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int count = 0;
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(title: const Text('Счётчик')),
body: Center(child: Text('Нажатий: $count')),
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() => count++),
child: const Icon(Icons.add),
),
);
}
const уменьшает число перестроений. Не создавайте тяжёлые объекты в build и не храните состояние в глобальных переменных.
Сборка под Linux
Релизная сборка создаёт самодостаточный каталог с исполняемым файлом и библиотеками. Его можно упаковать в архив, AppImage или Flatpak. Проверяйте на чистой машине: у разработчика часто есть лишние библиотеки.
flutter build linux --release
ls build/linux/x64/release/bundle
./build/linux/x64/release/bundle/myapp
ldd build/linux/x64/release/bundle/myapp | grep 'not found'
Для интеграции в меню нужен файл .desktop с абсолютным путём к исполняемому файлу и иконкой. Если приложение использует системные сервисы, проверьте права и наличие D-Bus в целевой сессии.
Мобильные сборки
Android собирается в APK для теста и в AAB для магазина. Подпись настраивают в android/key.properties, а сам ключ хранят вне репозитория. Для iOS нужен Mac и профиль provisioning.
flutter build apk --release
flutter build appbundle --release
keytool -genkey -v -keystore upload.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload
Не коммитьте key.properties и *.jks. В CI ключ подставляют из секретов, а сборку без подписи используют только для внутренних тестов.
Платформенный код
Когда пакета не хватает, пишут плагин или канал MethodChannel. На стороне Linux обработчик регистрируется в C++ коде runner, на стороне Dart вызывается метод. Канал стоит держать узким: передавать простые типы и не блокировать UI-поток тяжёлыми вызовами.
static const channel = MethodChannel('su.example/system');
final version = await channel.invokeMethod<String>('kernelVersion');
debugPrint('Ядро: $version');
Для файлов, уведомлений и трея сначала ищите готовый пакет.
Тесты, анализ и CI
Анализатор ловит ошибки типов и стилевые нарушения, тесты проверяют виджеты и логику. В CI эти шаги выполняют до сборки, чтобы не тратить время на артефакт с заведомо сломанным кодом.
dart format --set-exit-if-changed .
dart analyze
flutter test
flutter build linux --release
Кэшируйте ~/.pub-cache и каталог сборки, иначе зависимости будут скачиваться заново. Для Linux-раннера заранее ставьте GTK-зависимости.
Диагностика
Если приложение не запускается, смотрят вывод flutter run -v, журнал сессии и наличие библиотек. Пустой экран часто означает исключение в build, которое видно в консоли. Проблемы с Android обычно связаны с версией SDK, лицензиями или подписью.
flutter doctor -v
flutter run -d linux --verbose
flutter clean && flutter pub get
journalctl --user -n 50 --no-pager
После обновления Flutter полезно удалить build и .dart_tool, затем повторить pub get. Это решает большинство ошибок кэша, но не заменяет чтение сообщения компилятора.
Чек-лист
- Версии SDK и зависимостей зафиксированы.
- Сборка проверена на чистой системе.
- Секреты подписи не попадают в репозиторий.
- Анализатор и тесты проходят в CI.
- Для Linux подготовлены
.desktop, иконка и зависимости. - Понятно, какие платформы поддерживаются официально.
Итог
Dart и Flutter дают единый код для Linux и мобильных, но требуют дисциплины: фиксированных версий, тестов и проверки сборки на чистой машине. Начните с небольшого десктопного приложения, затем добавьте Android и платформенные каналы. Такой путь позволяет оценить расходы на сопровождение до того, как проект разрастётся.