https://velog.io/@jaybon/%ED%94%8C%EB%9F%AC%ED%84%B0-%EC%84%A4%EC%B9%98
참고
UI프레임워크 플러터
크로스 플랫폼
안드/ios/web/window/mac/linux
퓨시아OS -> 구글에서 밀고있는 OS
리액트 네이티브 vs 플러터
리액트 네이티브의 장점
-> 자바스크립트로 짤 수 있다.
-> 리액트를 알면 쉽게 접근.
-> 코드 푸시가 가능하다.
리액트 네이티브의 단점
-> 느리다
플러터의 장점
-> 빠르다
(코드가 안드/IOS코드로 변환)
플러터의 단점
-> 코드 푸시가 안된다.
-> Dart라는 언어를 배워야 한다.
(자바,JS 섞은 느낌)
모든 것들이 전부 Object 로 취급한다.
Variable 안에 넣을 수 있는 것은 전부 Object.
Fuction, number, null 전부 Objcet로 취급 된다.
변수에 넣을 수 있는 모든 것은 객체이며, 모든 객체는 클래스의 인스턴스로 취급.
List, List 같은 제너릭 type을 지원
Ex) List list = [0,1,”2”,3,false,true] 같은 형식이 가능 (전부 오브젝트로 취급되기 때문)

Typed 언어지만 자유도를 준다.
기본적으로는 typed 언어지만, Var, dynamic으로 선언하면 동적 type으로 사용 가능
Var : type을 지정하지 않아도 dart 에서 알아서 variable의 type이 뭔지 추측을 함. 다른 타입을 재대입 할 수 없음.
Dynamic :모든 dart 객체의 기본 Object, 명시적으로 사용, 서로 다른 타입을 지정할 수 있으며, 다른 타입을 재대입할 수 있음.

Public, private, protected 의 정의가 없으며, fuction()으로 정의 된다.
Private 인 은 class 안에서만 접근 가능한 것이 아닌, dart page 단위로 private 정의 된다.


Skia는 C++로 개발된 오픈 소스 2D 그래픽 라이브러리로 OpenGL의 Canvas를 사용해 렌더링을 합니다. Flutter에서 Dart로 코드를 작성하면 안드로이드나 IOS의 컴포넌트들을 거치지 않고, 바로 화면을 렌더링 할 수 있습니다. 2005년에 구글에 인수되었고, 현재까지도 계속해서 Google의 후원을 받고 있습니다. 2005년 구글이 인수한 기업으로는 안드로이드(8월), 스키아(11월) 등이 있습니다.

Skia가 Flutter의 그래픽 엔진으로 채택될 수 있었던 이유는 OpenGL을 사용하기 때문입니다. OpenGL은 그래픽 라이브러리 중 하나로써, 대표적인 그래픽 라이브러리로는 DirectX, Metal, OpenCV 등이 있습니다. DirectX는 마이크로소프트에서 개발했고, 윈도우와 엑스박스 등에서 사용합니다. Metal은 apple에서 개발한 라이브러리로 Mac, IOS에서 사용됩니다. OpenCV(Open Source Computer Vision Library)는 컴퓨터 비전 및 머신 러닝 라이브러리입니다. 여러 플랫폼들에서 사용하는 얼굴 인식, 개체 감지, 이미지 검색 등의 기능들을 개발 할 때 사용되는 라이브러리입니다. 이 외에도 하이레벨 툴인 유니티나 언리얼 엔진, Prodcessing, 3D Max 등이 있습니다.
OpenGL의 가장 큰 장점은 범용성입니다. 앞서 얘기한 DirectX는 윈도우에서 사용 가능하지만 Mac에서는 사용할 수 없습니다. 그런데 OpenGL은 윈도우와 Mac뿐만 아니라 모든 운영체제에서 사용할 수 있습니다. 이것이 flutter가 크로스플랫폼이 될 수 있었던 핵심 요소중 하나입니다.
그런데 어떻게 OpenGL는 모든 운영체제에서 사용할 수 있게 되었을까요? 이는 크로노스 그룹의 지속적인 관리하에서 모든 운영체제들이 OpenGL를 사용할 수 있도록 만들어져왔고, 만들어지고 있기 때문입니다.
좀 더 자세한 이해를 위해 OpenGL의 탄생 배경을 알아보겠습니다. OpenGL의 시초는 실리콘 그래픽스라는 워크스테이션 제조회사로 2000년대 초까지 3D 그래픽스 기술을 선도하던 회사였습니다. 특히 할리우드 영화 CG 작업에서는 100%는 SGI의 제품이 사용되었습니다. 대표적으로 터미네이터2, 쥬라기공원, 토이스토리 등이 있습니다. 하지만 PC의 발달과 함께 몰락하게 됩니다. PC에서도 SGI의 워크스테이션에서 하던 작업을 할 수 있기 때문입니다. 그러던 중 다행히도? 몰락 전에 OpenGL 1.0를 오픈소스로 배포했습니다. 그리고 이를 크로노스 그룹이 관리하기 시작한 것입니다.
크로노스 그룹은 2000년 1월에 설립되었는데, 표준 API의 제작을 통해 다양한 플랫폼과 장치에서 동적인 미디어의 가속화된 재생 및 저작이 가능하도록 만드는 것이 주 목적입니다. 구성원들로는 인텔, 엔비디아, 애플, 구글, 삼성, 퀄컴, 어도비, 오라클 등 굵직한 IT 기업들은 모두 들어가 있습니다.
Angular로 프로젝트를 진행하다 보면 AOT 나 JIT 이란 단어를 접하게 됩니다.
먼저, JIT이란 just-in-time의 약자로 런타임일 때 컴파일을 포함하여 코드를 실행하는 방법 중에 하나입니다.
런타임(runtime) : 프로그램이 사용자에 의해 실행되어 동작되어지는 때.
간단히 말하자면, JIT은 런타임 전이 아니라 필요할 때에 코드를 컴파일한다는 것입니다. 그렇다면 JIT은 어떻게 동작하는 걸까요?
JIT 컴파일러는 메소드가 호출될 때마다 바이트코드를 해석하는 대신, 실행중인 기계(컴퓨터)의 바이트코드를 기계어 명령어로 컴파일 한 다음 객체코드를 대신 호출합니다.
바이트코드(bytecode) : 인터프리터에 의해 바로 실행 될 수 있는 소스 코드와 기계어(machine code) 중간의 코드.
기계어(machine code) : 더이상의 변환 없이 컴퓨터의 물리적인 프로세서에서 바로 동작할 수 있는 이진 코드.
객체코드(object code) : 기계어 코드, 바이트코드 또는 둘 다로 구성된 컴파일러 또는 기타 변환기에 의해 생성된 코드. 즉, 아직 완전한 프로그램에 연결되지 않은 기계어 코드의 일부.
JIT이 모든 코드를 처음에 기계어로 변환하는 것은 아니고 필요한(바로 사용되는) 것들만 기계어로 변환합니다.
만약 메소드나 기능이 호출되었는데 기계어가 아니라면 기계어로 변환합니다. 즉, 필요할 때에만 사용하기 때문에 CPU의 부담을 줄일 수 있고 앱을 더 빠르게 렌더링합니다.
AOT란 ahead-of-time의 약자로 고수준의 언어들(C 또는 C++) 또는 자바 바이트코드와 같은 중간 표현을 시스템에 맞는 기계어로 변환하는 방식을 말합니다.
즉, 시스템에 맞게 컴퓨터가 바로 실행할 수 있는 기계어로 미리 컴파일 한다는 뜻이고 이로 인해 브라우저에서 더 빠른 렌더링을 제공합니다.
이 때 브라우저에서 더 빠른 렌더링을 제공한다는 말을 더 자세히 풀어보자면 JIT으로 Angular 프로젝트를 빌드했다면 브라우저에서 해당 프로젝트를 실행할 때 각 컴포넌트마다 JIT 컴파일러가 동작하기 때문에 각 페이지에 접속할 때마다 컴파일링을 하므로 렌더링 속도는 늦어질 수 밖에 없습니다.
반면에 AOT로 빌드했을 경우 미리 코드를 전부 시스템에 맞는 기계어로 변환한 것이기 때문에 브라우저에서 실행하면 추가적인 과정 없이 바로 렌더링이 되므로 브라우저에서 더 빠른 렌더링을 제공한다는 뜻입니다.
결론적으로 JIT과 AOT의 차이점은 아래와 같습니다.
JIT(just-in-time)은 런타임일 때 브라우저에서 애플리케이션을 컴파일 한다.
AOT(ahead-of-time)는 서버에서 빌드할 때 앱을 컴파일 한다.
JIT으로 빌드하면 브라우저에서 컴파일이 되므로 유저의 컴퓨터 성능에 따라 렌더링이 느릴 수 있다. 대신 빌드할 때 AOT보다 시간이 덜 걸리고 파일이 크지 않을 수 있다.
AOT로 빌드하면 미리 컴파일이 다 되어있어서 브라우저에서 바로 실행되므로 유저는 빠르게 페이지들을 사용할 수 있다. 대신 빌드할 때 JIT보다 시간이 더 걸리고 파일이 클 수 있다.
https://velog.io/@jaybon/flutter-store-%EC%98%88%EC%A0%9C
예제 참고
main 함수
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return const MaterialApp(
home: StorePage(),
);
}
}
class StorePage extends StatelessWidget {
const StorePage({Key? key}) : super(key: key);
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(25.0),
child: Row(
children: const [
Text("Woman", style: TextStyle(fontWeight: FontWeight.bold)),
Spacer(),
Text("Kids", style: TextStyle(fontWeight: FontWeight.bold)),
Spacer(),
Text("Shoes", style: TextStyle(fontWeight: FontWeight.bold)),
Spacer(),
Text("Bag", style: TextStyle(fontWeight: FontWeight.bold)),
],
),
),
Expanded(
child: Image.asset("assets/bag.jpeg", fit: BoxFit.cover),
),
Expanded(
child: Image.asset(
"assets/cloth.jpeg",
fit: BoxFit.cover,
)),
],
),
),
);
}
}
결과화면
