본문 바로가기
Study/Flutter

[Flutter] ensureInitialized() 언제, 왜 호출해야 하는가?

Firebase, sharedPreference , async-await 비동기 처리, Landscape (가로모드), Portrait (세로모드) 등...

이와 같은 라이브러리 사용이나 앱설정시에 꼭 해주어야 하는 저 메소드는 무엇을 의미하는가?

 

1. ensureInitialized란?

말 그대로 초기화된 상태를 보장한다는 의미입니다.

앱의 바인딩이 초기화되었는지를 확인하는데 사용됩니다.

 

 

2. ensureInitialized 종류

WidgetsFlutterBinding , ServicesBinding 크게 두가지가 있습니다.

WidgetsFlutterBinding.ensureInitialized()와 ServicesBinding.ensureInitialized() 모두 Flutter 애플리케이션의 바인딩이 초기화되었는지 확인하는 데 사용되지만 다른 바인딩 유형을 초기화하는 데 사용됩니다.

WidgetsFlutterBinding기본적인 Flutter 애플리케이션 바인딩으로서 위젯 렌더링 및 이벤트 처리와 같은 UI 관련 작업을 처리합니다.

WidgetsFlutterBinding.ensureInitialized()를 호출하면 WidgetsFlutterBinding이 초기화되어 애플리케이션에서 UI 렌더링이 가능해집니다.

반면에 ServicesBinding네트워크, 플랫폼 채널, 플러그인, 시스템 메시지, 키보드, 클립 보드 등과 같은 Flutter 프레임워크의 서비스에 대한 바인딩을 처리합니다.

ServicesBinding.ensureInitialized()를 호출하면 ServicesBinding이 초기화되어 애플리케이션에서 서비스 호출이 가능해집니다.

따라서, 기본적으로 WidgetsFlutterBinding.ensureInitialized()는 UI 관련 작업을 수행하기 위해 사용되고, ServicesBinding.ensureInitialized()는 Flutter 프레임워크의 서비스에 접근하기 위해 사용됩니다.

 

 

3. 어떠한 상황에서 사용하는가?

1. 비동기 작업에서 플러터 프레임 워크를 사용해야하는 경우:

애플리케이션의 바인딩이 초기화되지 않은 상태에서 비동기 작업을 수행하면 예기치 않은 결과가 발생할 수 있습니다. ensureInitialized() 함수를 호출하여 바인딩이 초기화될 때까지 기다렸다가 비동기 작업을 수행하면 안전하게 사용할 수 있습니다.

2. 일부 Flutter 플러그인에서 필요한 경우:

일부 플러그인은 플러터 바인딩이 초기화된 후에만 사용할 수 있습니다. 이러한 경우 플러그인을 사용하기 전에 ensureInitialized() 함수를 호출하여 바인딩이 초기화되도록해야합니다.

예를 들어, google_maps_flutter 플러그인을 사용하는 경우 ensureInitialized() 함수를 호출하여 Google Maps API 키가 초기화되고 맵을 사용할 수 있도록해야합니다.

따라서 ensureInitialized() 함수는 플러터 애플리케이션에서 비동기 작업이나 일부 플러그인에서 필요한 경우에 사용됩니다.

 

 

 
 

4. 사용 예제 코드

1) WidgetsFlutterBinding 예시 (세로모드 고정)

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

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  // 앱 위젯 바인딩후, 세로모드로 고정
  SystemChrome.setPreferredOrientations(
    [
      DeviceOrientation.portraitUp,
      DeviceOrientation.portraitDown,
    ],
  );  
  // Run the app
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('My App'),
        ),
        body: Center(
          child: Text('Hello, World!'),
        ),
      ),
    );
  }
}

위 예시 코드에서 WidgetsFlutterBinding.ensureInitialized() 함수는 비동기적인 코드가 없기 때문에 동기적으로 호출됩니다. runApp() 함수가 호출되기 전에 WidgetsFlutterBinding이 초기화되어 UI 작업이 가능해집니다.

주의할 점은, ensureInitialized() 함수를 호출하는 순서에 따라 결과가 달라질 수 있습니다. ensureInitialized() 함수를 호출하기 전에 다른 비동기 작업을 수행하는 경우, 초기화가 완료되기 전에 해당 작업이 실행될 수 있습니다. 따라서, ensureInitialized() 함수는 가능한한 초기화가 필요한 첫 번째 작업으로 수행해야합니다.

 

2) ServicesBinding 예시 

ServicesBinding.ensureInitialized() 함수는 비동기적인 코드에서 사용되는 경우가 많습니다. 다음은 main() 함수에서 ServicesBinding.ensureInitialized() 함수를 호출하고, SharedPreferences를 비동기적으로 로드하는 예시 코드입니다.

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart';

void main() async {
  // Ensure Flutter binding and services are initialized
  WidgetsFlutterBinding.ensureInitialized();
  await ServicesBinding.instance!.ensureInitialized();

  // Load shared preferences
  SharedPreferences prefs = await SharedPreferences.getInstance();
  String? name = prefs.getString('name');

  // Run the app
  runApp(MyApp(name: name));
}

class MyApp extends StatelessWidget {
  final String? name;

  MyApp({this.name});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'My App',
      home: Scaffold(
        appBar: AppBar(
          title: Text('My App'),
        ),
        body: Center(
          child: name != null ? Text('Hello, $name!') : Text('Hello, World!'),
        ),
      ),
    );
  }
}

위 예시 코드에서 ServicesBinding.ensureInitialized() 함수는 SharedPreferences를 비동기적으로 로드하기 전에 Flutter 프레임워크의 서비스에 대한 바인딩을 초기화합니다. 이렇게 하면 SharedPreferences.getInstance() 함수를 호출할 때 문제가 발생하지 않습니다.

await 키워드를 사용하여 ServicesBinding.ensureInitialized() 함수가 완료될 때까지 기다린 다음 SharedPreferences.getInstance() 함수를 호출합니다. 이렇게 하면 name 변수에 SharedPreferences에서 로드한 값이 할당됩니다.

주의할 점은, ServicesBinding.ensureInitialized() 함수를 호출할 때 await 키워드를 사용해야합니다. 그렇지 않으면 ServicesBinding이 초기화되기 전에 SharedPreferences.getInstance() 함수가 호출될 수 있습니다.

 
 
 
이렇게 ensureInitialized는 에러가 발생할 수 있는 부분을 방지하고 초기화를 보장해주기 위해 사용되는 메소드임을 확인하였습니다.
 

높은 안정성을 지닌 앱 개발을 하시길 바랍니다.

 

https://api.flutter.dev/flutter/widgets/WidgetsFlutterBinding/ensureInitialized.html

 

ensureInitialized method - WidgetsFlutterBinding class - widgets library - Dart API

WidgetsBinding ensureInitialized() Returns an instance of the binding that implements WidgetsBinding. If no binding has yet been initialized, the WidgetsFlutterBinding class is used to create and initialize one. You only need to call this method if you nee

api.flutter.dev