Multiplattform-Entwicklung für Android und Web? Kotlin macht‘s möglich!

Kotlin Multiplatform kann mehr als nur Mobile. Seit Kotlin 1.9.20 gilt es neben den Versionen für Android, iOS und Desktop für das Web als stabil.

In Pocket speichern vorlesen Druckansicht 2 Kommentare lesen

(Bild: Andrey Suslov/Shutterstock.com)

Lesezeit: 13 Min.
Von
  • Robin Holzwarth
Inhaltsverzeichnis

Kotlin Multiplatform (KMP) ist JetBrains' neues Steckenpferd und soll etablierten Frameworks wie Flutter oder React Native den Rang ablaufen. Googles Entscheidung, Kotlin zur offiziellen Programmiersprache für die Android-Entwicklung zu machen, bietet dafür beste Voraussetzungen. Denn Android-Entwicklerinnen und -Entwickler, die schon mit Kotlin arbeiten, können ihre Skills nutzen, um weitere Plattformen abzudecken. Neben Android-, iOS- und Desktop-Plattformen ermöglicht KMP es auch, für das Web zu entwickeln.

Dabei bietet KMP in vielen Bereichen sehr viel Flexibilität. So auch bei der Entscheidung, Frontend-Code mit Compose Multiplatform zwischen allen Zielplattformen zu teilen oder die jeweiligen Frontends nativ zu entwickeln.

Im Web zeigt der Flutter-Ansatz, den gesamten Code zu teilen, signifikante Schwächen. Webseiten sehen oft ungewöhnlich aus und verhalten sich manchmal nicht wie gewünscht, beispielsweise beim Scrollen. Zudem leiden die Sichtbarkeit und Auffindbarkeit der Webseite stark darunter. Sogar Flutter stellt deshalb die eigene Dokumentation nicht als Flutter-generierte Webseite, sondern als HTML-Seite zur Verfügung.

KMP lässt im Unterschied dazu den Developern mehr Freiheit. Das Frontend lässt sich bei Bedarf separat entwickeln. Diese Anpassungsfähigkeit hilft, die Herausforderungen einer einheitlichen Benutzeroberfläche – wie eine weniger personalisierte Nutzererfahrung – zu überwinden, während gleichzeitig Vorteile der plattformübergreifenden Entwicklung, wie Kosteneinsparungen, erhalten bleiben.

JetBrains' Entwicklungsumgebungen IntelliJ IDEA und Android Studio bieten einige Möglichkeiten, KMP-Projekte mithilfe eines Wizards zu generieren. Erfahrungsgemäß müssen Entwicklerinnen und Entwickler die Projekte oft selbst konfigurieren. Beispielsweise braucht es für die beiden Zielplattformen Android und Web drei Module (Abbildung 1): common, webApp und androidApp. Gradle-Build-Skripte verknüpfen die drei Module miteinander. Auf die Modulstruktur geht der Artikel im weiteren Verlauf ein, vorerst liegt der Fokus auf den Gradle-Skripten.

Modulstruktur einer KMP-Anwendung für Android und Web (Abb. 1).

Für die beiden Zielplattformen braucht es insgesamt vier Gradle-Build-Skripte.

Die build.gradle.kts-Datei in Kombination mit der settings.gradle.kts-Datei ist für den Build-Prozess des Projekts verantwortlich. Die beiden enthalten die Definitionen der globalen Bibliotheken, Abhängigkeiten und Plug-ins, die im gesamten Projekt zum Einsatz kommen. Zusätzlich findet hier auch die Versionsverwaltung statt – etwa die der Kotlin-Version. Die settings.gradle.kts-Datei listet alle Module auf, die der Build-Prozess berücksichtigen soll. Zusätzlich enthalten das Common-Modul sowie die Plattform-Module jeweils ein Gradle-Skript.

Das Gradle-Skript im Common-Modul konzentriert sich auf die plattformübergreifenden Aspekte der Anwendung. Es verwaltet die Bibliotheken und Abhängigkeiten, die im gesamten Projekt Verwendung finden – unabhängig von der spezifischen Plattform. Das Skript stellt sicher, dass die Kernfunktionalitäten und -logiken plattformunabhängig bleiben.

Jedes Plattform-Modul, wie das Android-Modul, hat sein eigenes build.gradle.kts-Skript. Es ist für das plattformspezifische Build-Setup zuständig und enthält Konfigurationen, die ausschließlich für die jeweilige Plattform relevant ist. Hier finden sich Definitionen zu plattformspezifischen Tasks, Dependencies und Plug-ins. Das Android-Modul enthält spezielle Einstellungen für das Android-Gradle-Plug-in und die SDK-Version.

Um eine Verbindung zwischen den Plattform-Modulen und dem Common-Modul herzustellen, ist in den Gradle-Skripten der Plattform-Module eine Abhängigkeit definiert: Implementation(project(„:common“)).

Das Hinzufügen dieser Zeile ermöglicht es, innerhalb der Plattform-Module auf den geteilten Code im Common-Modul zuzugreifen.

Die Fallstricke im Rahmen des Projektaufbaus liegen besonders bei inkompatiblen Versionen und Plug-ins, die sich gegenseitig und unerwünscht beeinflussen. Denn jedes Gradle-Skript führt Aufgaben aus, die mitunter undurchsichtig sein können, gerade dann, wenn Plug-ins im Spiel sind. Das kann dazu führen, dass der Build fehlschlägt und die Fehlersuche beginnt. Insbesondere wenn Entwicklerinnen und Entwickler die Gradle-Skripte nicht richtig verstehen, kann diese Fehlersuche kraftraubend sein. Der Copy-and-Paste-Ansatz scheint anfangs vielleicht attraktiv für Gradle-Neulinge, kostet aber auf Dauer viel mehr Nerven.