티스토리 뷰

flutter에서 앱을 시작전 초기화 과정중에 발생할 수 있는 이슈와 처리 방법에 대해서 다루고자 한다.

 

처음 플러터 앱을 만들면 기본 샘플앱에서 부터 시작 하는 경우가 많은데 실제 프로젝트에서 사용하기에는 조금 부족한 점이 있다.

우선 앱 시작 시점에 각종 리소스등와 firebase의 초기화가 필요하다. 그외 앱의 특성에 따라 splash화면 보다 먼저 내부적으로 초기화 해야 하는 것들이 있을수 있다.

 

예를 들면 필자가 사용중인 intl 라이브러인 intl_utils의 경우 다국어를 처리하는 용도로 사용중인데 화면에 어떤 종류의 메시지라도 표시 하기 위해서는 필수적으로 init가 되어야 한다.

await Messages.delegate.load(locale)

그런데 flutter의 main() 함수내에서 비동기 처리가 필요한 함수인 Messages.delegate.load(locale)이 필요하기 때문에 main함수를 async로 수행해야한다.

void main() { }  

(async 클래스로 만들어 준다)  -->

Future<void> main() async { }

보통의 경우 앱이 실행된 후 처음 화면이 나올때 까지 시간을 최소화 하기 위한 노력을 하기 마련이다.

그래서 main에서 runApp을 하기 전에 await를 하는 것은 좋은 방법이 아니다.

 

특히 firebase의 초기화의 경우 내부적으로 네트워크 통신등의 과정이 필요하기때문에 runApp호출전 await로 초기화 하는 것은 좋지 않고, complete이벤트를 받아서 따로 처리해주는 것이 좋겠다.

await Firebase.initializeApp();   
// Firebse의 초기화는 Fluter의complete call 함수를 등록해서 처리한다.
// 만약 Firebase initialize가 정상적으로 완료된 후 앱이 구동되어야 한다면 await firebase initialize가 완료되기를 대기 해야 한다.
Firebase.initializeApp().whenComplete(() => {});

물론 앱이 시작될때 사용중인 라이브러리나 모듈등을 모두 initilize완료 한 후 사용하는 것이 가장 안전한 방법이긴 하지만 앱이 구동되는 속도등을 고려해서 적절히 만들어 주는 것이 좋다.

Future<void> main() async {
...
    await Messages.delegate.load(locale); 
    runApp(MyApp());
...
}

 

위와 같이 main의 runApp전에 필요한 초기화를 수행할경우


NoSuchMethodError: The getter 'window' was called on null. Receiver: null Tried calling: window 와 같은 오류가 발생하기도 하는데 그럴때는 WidgetsFlutterBinding.ensureInitialized() 를 넣어 주면 된다.

 

비동기 처리가 가능한 main함수를 모두 완성하면 아래와 같이 된다.


Future<void> main() async {   
...
    WidgetsFlutterBinding.ensureInitialized(); 
    final locale = WidgetsBinding.instance.window.locales[0]; 
    await Messages.delegate.load(locale); 
    Firebase.initializeApp().whenComplete(() {  

    });   
    runApp(MyApp());   
...  
}
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함