금요일에 뭔가 대충 돌아가게 만들어 놓고, 주말 내내 방치했습니다.
달랑 문장 하나 출력해 놓고 말이죠.
그런데 대체 뭘 했길래 아무것도 안 하고 (사실은 환경 설정만 신나게 했는데) 창도 띄우고 문장도 출력하고 하는 걸까요?
오늘은 플러터 프로젝트의 개략적인 구조를 한 번 살펴보겠습니다.
일단 기본적인 형상은, lib 디렉터리 밑에 있는 main.dart 파일이 플러터 중심 기능을 하는 것처럼 보이는데요.
그러니까, 각각의 앱에서는 이 플러터 모듈이 왠지 library처럼 쓰이고 있는 듯한 기분이 듭니다.
과연 그런지, 하나하나 좀 뜯어보죠.
android
제일 위에는 android를 위한 구조가 있습니다.
android는 사실 kotlin 소스 안에서는 크게 하는 일이 없습니다.
그냥 MainActivity 생성하는 게 끝? 인 것 같지만, 저 Activity는 FlutterActivity라는 특수한 Activity를 계승받네요.
안드로이드 모르시는 분들을 위해 추가로 말씀드리면, 액티비티(Activity)는 화면 하나를 책임지는 패키지라고 생각하시면 됩니다.
대부분의 앱은 이 액티비티 하나로 간편하게 만들고, 여러 페이지가 되면 이 숫자가 늘어나서 복잡한 구조가 됩니다.
하여튼 저 특이한 Activity의 출처를 확인하려면 빌드 패키지를 구성할 때 쓰는 파일인 build.gradle을 확인해 봐야겠네요.
저 위에 보면 dev.flutter.flutter-gradle-plugin이 보이는데요. 저 안에 위의 그 클래스가 정의되어 있습니다.
이 안에 안드로이드의 메인 화면과 플러터에서 작업한 화면을 연결하는 플러그인 설정들이 다 모여있죠.
음 근데... 안드로이드의 버전이나 Java 버전들은 확실히 현재 지원하는 버전보다 낮아서,
실제로 배포할 때는 손을 보셔야 합니다. 이건 나중에 배포 관련 얘기를 할 때 (언제?) 말씀드리는 것으로 하죠.
iOS
iOS는 android와 구조가 비슷(?)합니다.
iOS는 기본적으로 사용하는 프로그래밍 언어가 Swift인데요.
플러터 코드를 라이브러리 화한 부분과의 통신 처리 부분은, 이전에 쓰던 언어인 Objective-C 형태로 사용합니다.
(C언어는 아니고요, C 비슷한 다른 언어입니다. 익숙해지면 쓸만한데 그 익숙해지기가 아주 골치 아픈(...) 언어입니다;)
해서, iOS의 메인(정확히는 애플 계열에서 쓰는 코코아 프레임워크 메인)에 해당하는 AppDelegate.swift 형태가 저렇습니다.
그런데, 실제 하는 일은 코드가 복잡하다 뿐이지, 위에서 보셨던 안드로이드 MainActivity.kt 와 크게 다르지 않습니다.
안드로이드도 저런 과정을 거치지만, 실제 코드는 다 FlutterActivity 안에 숨겨놓았을 뿐이죠.
macOS
macOS는 iOS와 프로젝트 구조는 동일한데, 실제 앱을 구동하는 구조는 알아보기 쉽게 되어 있습니다.
macOS는 기본적으로 NSWindow 클래스로 창을 만드는데요.
그 녀석을 계승받은 MainFlutterWindow 클래스를 생성한 다음 그 녀석 안에서 플러그인을 등록하게 되어 있습니다.
즉 이 창 안에서 플러터에서 작업한 라이브러리 형태의 모듈들을 구동하는 형태로 되어 있는 거죠. 뭔가 이해가 쉽습니다?
web
web은 굉장히 단촐합니다. web 자체로는 거의 하는 게 없어서 그렇습니다.
잘 보시면, 아주 심플한 index.html 이 진행되다가, 마지막에 하나의 js (자바스크립트) 파일이 보입니다.
flutter_bootstrap.js 파일이 있죠?
네. 실제로 플러터 웹이 구동될 때는, 빌드 시점에 dart 프로젝트를 저 js 파일로 컴파일해 두는 겁니다.
dart 코드들이 웹 상에서 동일한 기능을 하는 자바스크립트로 죄다 변환되는 거죠. 물론 다 암호화된 형태로 말이죠. 끝.
windows
windows 쪽은 좀 더 상세한 구조를 볼 수 있습니다.
돌아가기 위해서 약간 복잡한 구조를 가지고 있네요.
.NET 프레임워크에서 사용하는 C#은 뭔가 코드들이 복잡하게 보이지만, 사실 macOS에서 하는 작업과 큰 차이가 없습니다.
결과적으로 macOS의 MainFlutterWindow에 해당하는 FlutterWindow라는 클래스가 있는데,
얘는 직접 window로 뜨는 것이 아니라, 윈도에서 기본으로 사용하는 Win32Window를 먼저 프레임으로 생성해 두고,
그 프레임 안에 child content의 형식으로 뜨는 것이 차이가 있는 정도네요. (뭔가 어려운 말입니다만 일단 넘어가주세요 ㅜㅜ)
그 외 리눅스도 있지만, 일단은 구구절절인 듯하여(...) 일단은 뺐습니다.
관심 있는 분들 있으시면 나중에 또 소개하는 것으로 하겠습니다.
OS별로 하나하나 잡고 파 보는 게 정석이긴 한데, 그러려면 또 몇 날 며칠이 걸릴지도 모르겠고,
뭣보다 뭔가 해보시는 분들이 그거 보다가 지치실 테니, 궁금하신 부분을 직접 찾아보실 수 있는 수준으로만 소개해 드렸습니다.
혹여 좀 전문적으로 아시는 분들이 보시고 "아 이건 아닌데!" 하시고 지적해 주시면 제가 넙죽 엎드리고 고치면 더 좋겠네요 (_ _)
다음에는 이제 본체(?)인 main.dart 관련한 얘기하고, 이 부분을 수정하면 어떻게 달라지는지 한 번 보도록 하겠습니다.