패키지, 저장소 및 앱 카테고리 검색

app_runner 표지
패키지 상세v2.2.2

app_runner

프로처럼 Flutter 앱을 시작하세요! AppRunner는 애플리케이션의 빠르고 제어 가능한 실행을 위한 구성 도구입니다.

AndroidiOSWebmacOSWindowsLinux
30일 다운로드
165
좋아요
61
Pub 점수
160

패키지 설치

flutter pub add app_runner

패키지 개요

공개 정보를 바탕으로 생성한 선택 가이드입니다.

AppRunner는 개발자가 사용자 정의 구성으로 애플리케이션을 시작할 수 있도록 해주는 Flutter 유틸리티 패키지입니다. 제어되고 효율적인 앱 시작을 보장합니다. 여러 플랫폼에서 시작 매개변수, 환경 설정 및 초기화 워크플로우를 관리하는 과정을 단순화합니다. 개발, 테스트 및 스테이징 환경에 적합하며, 작업 흐름의 일관성을 높이고 설정 시간을 줄입니다. Android, iOS, Web, macOS, Windows, Linux를 지원하여 현대적인 Flutter 프로젝트에 대한 크로스플랫폼 유연성을 제공합니다.

사용 사례

  • 사용자 정의 구성으로 빠른 앱 실행
  • 개발 및 테스트 환경 설정
  • 스테이징 환경 구성
  • 크로스 플랫폼 앱 초기화
  • 자동화된 빌드 및 실행 워크플로우

주요 기능

  • 사용자 지정 가능한 시작 설정
  • 다중 플랫폼 지원
  • 환경 인식 시작
  • 간소화된 초기화
  • CI/CD 파이프라인과의 통합

적합한 대상

  • Flutter 개발자
  • 테스트 자동화 엔지니어
  • DevOps 팀
  • 크로스플랫폼 앱 유지보수자
  • 빠른 프로토타이핑

고려 사항

  • 각 환경마다 수동 구성이 필요합니다
  • 시작 시 사용자 지정에 제한됨
  • 런타임 구성 변경 없음
  • 출시 전 설정에 가장 적합
  • 올바른 프로젝트 구조에 따라 달라짐

원본 README

연결된 소스 저장소의 README 원문 스냅샷입니다. 최신 내용은 저장소에서 확인하세요.

AppRunner

pub package License

Launch your Flutter app like a pro! AppRunner is a configurator for quick and controlled launch of your application, with features that runApp does not have.

We solve problems of brand presence on mobile devices, specializing in development of mobile applications and services in the b2c segment.

Subscribe for the latest updates:


Features

  • Get your application up and running quickly.
  • Allows you to run code without blocking your application from launching.
  • Show your independent splash screen while loading the app. AppRunner does not block the first call of the widget, do you practically won't see the native splash screen.
  • Allows you to reload the widget tree if you need it.
  • Your code will run in a safe environment for both Dart code and Flutter code. AppRunner catches and handles errors, preventing your application from breaking at runtime.
  • Configuring the zone of your application is much easier.
  • With AppRunner you can easily override ErrorWidget for debug and release mode.
  • Lets you just use your WidgetsBinding implementation.
  • And the very last and most important argument to use AppRunner in your application, it is very easy to integrate into your application, and its configuration does not take much time.
Splash Screen Debug Error Screen Release Error Screen
run debug-error release-error

Installing

BREAKING: Note, starting with version 2.2.0, Flutter 3.10.0+ is used by default. If you need to use a Flutter version lower than 3.10.0, then use package version 2.1.2 and below.

Add this to your package's pubspec.yaml file:

dependencies:
  app_runner: <last version>

Usage

This is how your application launch looked like before:

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

It is simply by attaching your widget to the root. But in order to catch errors, it was necessary to use runZonedGuarded, then our code will become like this:

import 'dart:async';

import 'package:flutter/material.dart';

void main() {
  runZonedGuarded<void>(
    () {
      runApp(MyApp());
    },
    (Object error, StackTrace stackTrace) {...},
    zoneValues: ...,
    zoneSpecification: ...,
  );
}

But we also need to initialize some code to launch the application, for example Firebase:

import 'dart:async';

import 'package:flutter/material.dart';
void main() {
  runZonedGuarded<void>(
    () async {
      WidgetsFlutterBinding.ensureInitialized();

      await Firebase.initializeApp();

      HydratedBloc.storage = await HydratedStorage.build(
        storageDirectory: await getApplicationDocumentsDirectory(),
      );

      Bloc.observer = MyBlocObserver();

      runApp(MyApp());
    },
    (Object error, StackTrace stackTrace) {},
    zoneValues: ...,
    zoneSpecification: ...,
  );
}

And what do we have:

  • The launch of the widget is blocked by the third-party code.
  • The splash screen is implemented in MyApp, that is, it will be present in the tree when it is no longer needed.
  • Not the most beautiful and understandable code.

Let's fix this with AppRunner (all possible parameters are shown here, it is not necessary to use all of them):

import 'package:app_runner/app_runner.dart';
import 'package:flutter/material.dart';

void main() {
  final WidgetConfiguration widgetConfiguration = WidgetConfiguration(
    child: AppBuilder<String>(
      preInitialize: (WidgetsBinding binding) async {
        // Custom code initialization.
        // You don't need to call WidgetsFlutterBinding.ensureInitialized();
        // WidgetsBinding is also available here if you need it.

        await Firebase.initializeApp();

        HydratedBloc.storage = await HydratedStorage.build(
          storageDirectory: await getApplicationDocumentsDirectory(),
        );

        Bloc.observer = MyBlocObserver();
        
        return 'Mad Brains';
      },
      // Our application
      builder: (
        BuildContext context,
        AsyncSnapshot<String?> snapshot,
        Widget? child,
      ) {
        late final Widget _child;
        switch (snapshot.connectionState) {
          case ConnectionState.none:
          case ConnectionState.active:
          case ConnectionState.waiting:
            _child = const Splash(); // show Splash
            continue display;
          case ConnectionState.done:
            final String? data = snapshot.data; // data from preInitialize
            log(data);
            _child = const MyApp(); // show App
            continue display;
          display:
          default:
            return AnimatedSwitcher(
              duration: const Duration(milliseconds: 150),
              child: _child,
            );
        }
      },
    ),
    errorBuilder: (BuildContext context, FlutterErrorDetails errorDetails) => MyErrorScreen(errorDetails), // Our flutter error screen during debugging
    releaseErrorBuilder: (BuildContext context) => MyReleaseErrorScreen(), // Our flutter error screen during release
    onFlutterError: (FlutterErrorDetails errorDetails) {
      // Flutter error handling
      log(
        errorDetails.toStringShort(),
        name: 'onFlutterError',
        stackTrace: errorDetails.stack,
        error: errorDetails.exception,
      );
    },
    initializeBinding: () => CustomWidgetsFlutterBinding(), // Creating your WidgetsFlutterBinding
  );

  final ZoneConfiguration zoneConfiguration = ZoneConfiguration(
    onZoneError: (Object error, StackTrace stackTrace) {
      // Dart error handling
      log(
        error.runtimeType.toString(),
        name: 'onZoneError',
        stackTrace: stackTrace,
        error: error,
      );
    },
    zoneValues: ..., // Your zone parameters
    zoneSpecification: ..., // Your zone specifications
  );

  appRunner(
    kIsWeb
        ? RunnerConfiguration(
            widgetConfig: widgetConfiguration,
            // optional, isolate error handling
            onPlatformError: (Object exception, StackTrace stackTrace) {
              log(
                exception.runtimeType.toString(),
                name: 'onPlatformError',
                stackTrace: stackTrace,
                error: exception,
              );

              return false;
            },
          )
        : RunnerConfiguration.guarded(
            widgetConfig: widgetConfiguration,
            zoneConfig: zoneConfiguration,
          ),
  );
}

If you need to reload the widgets, you can do:

reloadWidget(context);

// or

context.reloadWidget();

Example

The Example is in the corresponding folder

카테고리

소스 저장소

이 패키지를 사용하는 프로젝트

아직 데이터가 없습니다.