Как исправить проблему случайного закрытия (краша) Flutter-приложения?

«Как исправить проблему случайного закрытия (краша) Flutter-приложения?» — вопрос из категории Рендеринг и производительность, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Краши обычно вызваны необработанными исключениями. Моя стратегия отладки выглядит так:

1. Локализация ошибки:

  • Запускаю приложение в режиме отладки (flutter run). Необработанные исключения выводятся красным в консоли с полным стектрейсом.
  • Использую try-catch в потенциально проблемных местах, особенно вокруг асинхронных операций (сеть, работа с файлами, плагины).
    try {
    final response = await http.get(someUri);
    // Обработка данных
    } on SocketException catch (e) {
    // Нет сети
    showErrorSnackbar('Проверьте подключение');
    } catch (e, s) {
    // Любая другая ошибка
    debugPrint('Ошибка: $enСтек: $s');
    // Отправляю отчет в Crashlytics
    await FirebaseCrashlytics.instance.recordError(e, s);
    }

2. Установка глобальных обработчиков: Чтобы отловить ошибки, пропущенные try-catch (например, в колбэках виджетов), настраиваю:

void main() {
  FlutterError.onError = (details) {
    // Логирую в консоль и отправляю в сервис мониторинга
    FirebaseCrashlytics.instance.recordFlutterError(details);
  };
  PlatformDispatcher.instance.onError = (error, stack) {
    // Обработка ошибок на уровне платформы (не-Flutter)
    FirebaseCrashlytics.instance.recordError(error, stack);
    return true; // Предотвращаем краш приложения
  };
  runApp(MyApp());
}

3. Проверка типичных источников крашей:

  • Null-safety: Включаю строгий режим анализатора (analysis_options.yaml) и исправляю все предупреждения.
  • Состояние виджетов: Проверяю, что не обращаюсь к context или widget после вызова dispose() в StatefulWidget.
  • Нативные плагины: Обновляю плагины до последних версий, проверяю соответствие версий Android/iOS.
  • Память: Использую DevTools для поиска утечек, особенно в глобальных объектах, стримах или контроллерах анимации, которые не закрываются.

4. Мониторинг в продакшене: Обязательно интегрирую Firebase Crashlytics. Это позволяет видеть стектрейсы крашей на устройствах реальных пользователей, их частоту и устройства, на которых они происходят.