2024-03-05 00:34:31 +01:00

128 lines
5.2 KiB
Markdown

<!-- TODO: Was ist Flutter? -->
<!-- - Provide a focused overview of Flutter's architecture (widgets, rendering engine, Dart).
- Discuss reasons why Flutter is gaining interest for non-mobile applications -->
## Flutter
Flutter ist ein von Google entwickeltes
quelloffenes Benutzerschnittstellen-Entwicklungs-Kit,
welches die effiziente Entwicklung ansprechender
Benutzeroberflächen für mobile, Web- und
Desktop-Anwendungen ermöglichen soll. Es wurde
2017 von Google veröffentlicht und ist
BSD-lizenziert [@3ClauseBSDLicense2011].
Die zunehmende Verbreitung mobiler Geräte und Betriebssysteme
stellt die effiziente Anwendungsentwicklung vor Herausforderungen.
Plattformübergreifende Frameworks wie Flutter zielen darauf ab,
diese Herausforderungen zu mildern, indem sie ein einheitliches
Toolset zum Erstellen von Benutzeroberflächen (GUIs) bereitstellen,
die nahtlos über verschiedene Plattformen hinweg funktionieren.
Dieses Kapitel befasst sich mit der grundlegenden Architektur
von Flutter.
### Flutters Architektur
Flutter verwendet eine modulare, geschichtete Architektur. Dieses
Design besteht aus unabhängigen Bibliotheken, die jeweils von der
darunter liegenden Schicht abhängig sind, was lose Kopplung und
Flexibilität gewährleistet. Dieser Ansatz fördert die Anpassbarkeit
und die Möglichkeit, Framework-Komponenten nach Bedarf zu ersetzen. [@FlutterArchitecturalOverviewb]
Die folgende Abbildung \ref{flutterArch} zeigt die Architektur von Flutter:
\pagebreak
```{=latex}
\begin{figure}[ht]
\centering
\caption{Flutter Architektur}
\includegraphics[width=9cm]{assets/flutter/archdiagram.png}
\label{flutterArch}
<!-- prettier-ignore -->
\caption*{
```
Quelle: @FlutterArchitecturalOverviewb
```{=latex}
}
\end{figure}
```
Das Kernelement von Flutter ist die Engine, die in C/C++ geschrieben
ist. Sie ist für das Rastern zusammengesetzter Szenen verantwortlich,
sobald ein neues Bild gezeichnet werden muss. Sie übernimmt alle
Aufgaben zur Darstellung der Benutzeroberfläche.
Auf der Engine liegt das Flutter-Framework, das in der Programmiersprache
Dart geschrieben ist. Diese Ebene bietet ein modernes, reaktives Framework,
das zum Aufbau der Benutzeroberfläche verwendet wird. In der Entwicklung
von Flutter Anwendungen wird meistens nur diese Flutter-Framework Ebene
verwendet und die komplette Flutter Anwendung wird meist nur im
Framework Teil in Dart geschrieben.
Die niedrigste Ebene ist der Embedder, dessen Aufgabe es ist,
die Rendering-Fläche bereitzustellen, die Eingaben zu verarbeiten
und Zugriff zu Dart Anwendungs-Snapshots zu ermöglichen. [@gardeFlutterRaspberryPi2018]
Die Flutter Engine hat hierzu eine C API, welche in einer einzelnen
C Header-Datei definiert ist. [@theflutterauthorsEngineShellPlatform] Diese API Punkte müssen von dem
Embedder angesprochen werden.
<!-- ```{#test .dart .number-lines caption="Example Dart test" captionpos=t}
import 'package:retry/retry.dart';
final response = await retry(
// Make a GET request
() => http.get('https://google.com').timeout(Duration(seconds: 5)),
// Retry on SocketException or TimeoutException
retryIf: (e) => e is SocketException || e is TimeoutException,
);
print(response.body);
``` -->
### Deklarative Programmierung in Flutter
Deklarative Programmierung ist ein Programmierparadigma, bei dem
der Programmierer den gewünschten Endzustand der Anwendung
beschreibt, anstatt die Schritte zu definieren, die zur Erreichung
dieses Zustands erforderlich sind. Dieses Paradigma ist in Flutter
zentral, da es die Entwicklung von Benutzeroberflächen erleichtert.
Die Benutzeroberfläche wird als Baum von Widgets dargestellt, die
jeweils den gewünschten Zustand der Benutzeroberfläche beschreiben.
Wenn sich der Zustand ändert, wird der Baum der Widgets neu
gerendert, um den neuen Zustand widerzuspiegeln. [@googleinc.IntroductionDeclarativeUI]
\lstinputlisting[language=Java, caption=Beispiel für deklarative Programmierung mit Flutter, linerange={65-73}, captionpos=t]
{code/flutter_architecture/lib/main.dart}
Wie im Code-Beispiel zu erkennen definiert der Entwickler hier
ein neues Widget `TextWidget`, welches einen Text als Parameter erhält
und diesen als Text-Widget mit dem im Parameter übergebenen Text
zurückgibt. Dieses Widget wird dann in der "build" Methode erstellt.
An einer gegebenen Stelle im Code kann der Entwickler nun dieses
`TextWidget` folgendermaßen verwenden:
```{#test .dart .number-lines caption="Nutzung des TextWidgets" captionpos=t}
TextWidget("Hello World");
```
Hier wird der Text "Hello World" als Parameter an das `TextWidget`
übergeben und das Widget wird an der beliebigen Stelle in der Anwendung
angezeigt wo es so eingesetzt wurde. Wenn nun aber eine dynamische
Variable an den Text übergeben werden soll, kann dies einfach
durch die folgende Deklaration geschehen:
```{.dart .number-lines caption="Nutzung des TextWidgets mit dynamischer Variable" captionpos=t}
String text = "Hello World";
TextWidget(text);
```
Falls nun die Variable `text` sich ändert, wird das `TextWidget`
automatisch neu gerendert und der neue Text wird angezeigt.
Der Entwickler muss sich also nicht darum kümmern, dass das Widget
neu gerendert wird, das ist deklarative Programmierung in Flutter.
Das Framework übernimmt das für den Entwickler automatisch.