brunch

You can make anything
by writing

C.S.Lewis

by myner Dec 28. 2018

[Flutter] 03. 네이티브와의 구조

Android, iOS와 Flutter의 구조 관계

(본 글은 공부하며 적은 글로서 100% 맞음을 보장할 수 없습니다. 틀린 곳은 조언해주시면 감사하겠습니다!)


Dart Developers Korea  오픈채팅방 https://open.kakao.com/o/gYyufB6 


지난 글에(https://brunch.co.kr/@myner/4) 이어서 Flutter 구조를 계속 보자!



iOS부터 구조를 보면 아래 그림과 같다. FlutterViewController를 통해서 Native와 연결된 부분을 다 관리하게 된다. 그 말인 즉 AddChildViewController 및 removeFromParentViewController를 통해 FlutterViewController를 직접 재사용할 수도 있다.



Android의 구조는 아래와 같다. FlutterNativeView를 이용하여 Native를 컨트롤한다고 보면 된다.


그림을 보면 비슷한 부분이 많지만 다른 점이 있는데 iOS의 경우 mm파일 사용 시 네이티브 코드를 플랫폼 코드와 바로 엮어서 사용이 가능하다. 여기서 네이티브는 네이티브의 네이티브 즉 C, C++로 구현된 것들을 말한다. 안드로이드의 경우 NDK를 사용해야만 한다.


사실 이 부분이 C/C++ 코드를 엮어서 개발을 직접 할 경우 iOS가 편할 수밖에 없다. 필자의 경우 렌더링 엔진을 개발한 적이 있는데 NDK를 이용할 때 디버깅 시에도 데이터 값을 주고받을 때도 많이 불편하였다. 물론 필자의 실력이 부족하여 발생한 경험일 수 있다...


사실 우리가 Flutter로 앱 개발한 다 고하면 이런 걸 몰라도 상관없을 것이다.

하지만 궁금하지 않은가? 대체 무슨 어떠한 일이 벌어지길래  네이티브 엡 개발의 퍼포먼스를 내는 것인지? 그 아래에서 무슨 일을 하고 있는지? 궁금하리라 생각한다. 필자만 그런 게 아니 였으면 좋겠다...


Flutter 아키텍처 심화 ver

Flutter System Overview (https://flutter.io/docs/resources/technical-overview)


플러터는 그림처럼 세 가지로 구성되는데

맨 위의 Framework는 우리가 Flutter에서 실제 구현하는 것들을 위한 부분들이 들어가 있다. 이 부분의 핵심은 flutter 패키지에서 sky_engine이란 곳이다. 이 안에 i/o, async, ui(dart: ui라이브러리는 Flutter프레임워크와 엔진 간의 인터페이스를 제공)  및 기타 내용들이 들어가 있다.


가운데 Engine는 C++로 구성되며 Skia, Dart 및 Text 등이 포함된다. Skia는 다양한 하드웨어 및 소프트웨어 플랫폼에 공통 API를 제공하는 오픈소스 2D 그래픽 라이브러리이며 구글 크롬, 크롬 OS, 안드로이드, 모질라 파이어폭스, 파이어폭스 OS 등등 다양한 곳에서 사용된다. Dart 파트에는 주로 Dart 런타임, GC 및 디버그 모드인 경우 JIT 지원을 위한 파일이 포함된다. 릴리즈 및 프로파일 모드에서 AOT는 원시 Arm 코드로 컴파일되며 JIT 부분이 없다.

맨 아래 Embedder는 Flutter를 다양한 플랫폼에 임베드하는 임베디드 레이어로서, Surface 설정, 스레드 설정 및 플러그인 렌더링을 포함한다.


iOS를 예로 들면,

Flutter.framework는 Flutter 아키텍처의 엔진 부분과 Embedder에 해당한다.

실제로 Flutter.framework는 저장소의 /bin/cache/artifacts/engine/ios에 있으며 기본적으로 구글 저장소에서 가져온다. 커스텀을 하고 싶을 경우 Ninja 빌드 시스템을 사용하여 엔진 소스코드를 생성할 수 있다.


Flutter 관련 코드의 최종 프러덕트는 App.framework(다트 코드 생성), Flutter.framework(엔진)이다.

이 둘을 합쳐서 최종적으로 보이는 모습으로 된다.



실제 렌더링, 이벤트 처리 등의 로직은 아래와 같다.


ios의 경우 엔트리 포인트를 기준으로 정리하면 이런 구조를 가지게 된다.

Android의 경우를 보면


vm_shnapshot_data, vm_snapshot_instr은 ARM 명령어이다.



사실 정리하면서도 잘 모르겠다.


필자는 위에서도 모든 글에서 다 밝히고 있지만 필자도 자료수집 및 공부를 하며 얻은 정보이기 때문에 이게 맞는지 모르겠다. 글을 쓰는 동안 바뀔 수도 있고 이미 바뀐 내용을 지난 내용을 쓸 수도 있고 글을 보는 시점에선 이미 다른 구조일 수도 있다. 하지만 필자가 믿고 있는 것이 있다. 그건 바로 그 기반은 바뀌지 않을 것이란 거다. 구조가 조금씩 바뀔 수 있고 클래스가 쪼개지고 함수가 쪼개지고 그럴지라도 한동안 그 기본 디자인은 바뀌지 않을 거란 것.


다음 글(https://brunch.co.kr/@myner/5)부터는 렌더링에 다가가 보고자 한다.


<참고문헌>

https://flutter.io/docs/resources/technical-overview

https://github.com/flutter/flutter  
https://github.com/flutter/engine

https://docs.flutter.io/index.html 

https://www.yuque.com/xytech/flutter/sh4fbm 

https://github.com/flutter/flutter/wiki/Flutter%27s-modes 
https://docs.google.com/presentation/d/1cw7A4HbvM_Abv320rVgPVGiUP2msVs7tfGbkgdrTy0I/edit#slide=id.p 
https://docs.google.com/presentation/d/1B3p0kP6NV_XMOimRV09Ms75ymIjU5gr6GGIX74Om_DE/edit#slide=id.g238c12bdda_0_8 




브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari