Co wiesz o wewnętrznej strukturze Flutter?
sobes.tech AI
Odpowiedź od AI
Rdzeń Fluttera składa się z silnika, frameworka i widżetów.
-
Silnik Flutter: Napisany w C++ i zapewnia niskopoziomowe API do renderowania, obsługi tekstu, wątków i wtyczek. Bezpośrednio współpracuje z platformą (iOS, Android, Web, Desktop) i API graficznymi (np. Skia). Zarządza renderowaniem, operacjami asynchronicznymi i cyklem życia aplikacji.
-
Framework Flutter: Napisany w Dart i zapewnia warstwę abstrakcji nad silnikiem. Zawiera wiele gotowych komponentów:
- Foundation: Podstawowe klasy i funkcje pomocnicze.
- Rendering: Warstwa do zarządzania drzewem obiektów renderujących i ich rysowaniem.
- Widgets: Podstawowe elementy UI tworzące drzewo widgetów.
- Material Design i Cupertino: Zbiory widgetów implementujących style Material Design i iOS.
-
Widżety: W Flutter wszystko jest widgetem. Widgety opisują konfigurację UI. Istnieją dwa główne typy:
- StatelessWidget: Widget bez zmiennego stanu wewnętrznego. Jego UI zależy tylko od parametrów wejściowych (
properties). - StatefulWidget: Widget, który może mieć zmienny stan. Składa się z samego widgetu i obiektu
State, w którym przechowywany jest stan i logika budowania UI (build).
- StatelessWidget: Widget bez zmiennego stanu wewnętrznego. Jego UI zależy tylko od parametrów wejściowych (
Proces renderowania:
- Build: Framework wywołuje metodę
build()widgetu, która zwraca drzewo innych widgetów. - Drzewo elementów: Na podstawie drzewa widgetów tworzone jest drzewo elementów (
Element Tree), które reprezentuje strukturę UI. Elementy łączą widgety z odpowiadającymi im obiektami renderującymi. - Drzewo obiektów renderujących: Elementy tworzą i zarządzają drzewem obiektów renderujących (
Render Object Tree). Obiekty renderujące odpowiadają za układ, malowanie i hit testing. - Malowanie: Silnik używa Skia (na urządzeniach mobilnych i desktopie) lub CanvasKit (w webie) do rysowania obiektów renderujących na ekranie.
Programowanie reaktywne:
Flutter używa podejścia reaktywnego do budowania UI. Gdy stan się zmienia, framework przebudowuje tę część drzewa widgetów, która od niego zależy. Dzieje się to automatycznie i efektywnie dzięki mechanizmowi diffing i szybkiemu tworzeniu oraz niszczeniu widgetów.
Hot Reload i Hot Restart:
- Hot Reload: Wstrzykuje zaktualizowany kod Dart do działającej aplikacji bez utraty stanu. Idealne do szybkich iteracji UI.
- Hot Restart: Restartuje aplikację od zera z zaktualizowanym kodem i zresetowanym stanem. Używany, gdy Hot Reload nie działa, np. przy zmianach w
initStatelub zmiennych globalnych.
Kod specyficzny dla platformy:
Flutter pozwala na interakcję z natywnymi API platformy przez kanały platformowe (Platform Channels). Umożliwia to wywoływanie metod natywnego kodu (Java/Kotlin na Androidzie, Swift/Objective-C na iOS) i odbieranie wyników z powrotem w Dart.
// Przykład użycia kanału platformowego
import 'package:flutter/services.dart';
static const platform = MethodChannel('samples.flutter.dev/battery');
Future<void> getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Poziom baterii: $result %.';
} on PlatformException catch (e) {
batteryLevel = "Nie można uzyskać poziomu baterii: '${e.message}'.";
}
// Aktualizacja UI
}