Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 deletions content/kotlin/area.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,30 @@ title: Kotlin & Android
short: Kotlin
tagline: Moderne Android-Apps – von der ersten Zeile bis in den Play Store.
description: >
Kotlin als Sprache, Coroutines und Flow, Jetpack Compose, Architektur mit
ViewModel und Repository, Room, Netzwerk, Tests und Release. Dazu der
Praxis-Track mit 100 Aufgaben aus dem echten Code von Bear.
Kotlin als Sprache, Coroutines und Flow, Jetpack Compose bis zu eigenen
Layouts und Animationen, Architektur mit Modulen, Room, Paging und Netzwerk,
Tests, Performance und Release. Dazu der Praxis-Track mit 100 Aufgaben aus
dem echten Code von Bear.
color: "#A98BFF"
order: 1
outcomes:
- Du schreibst idiomatisches Kotlin mit Null-Sicherheit, Datenklassen, Sealed Types und Collections-Operationen.
- Du baust Oberflächen mit **Jetpack Compose** und verstehst Zustand, Recomposition und Side Effects.
- Du baust Oberflächen mit **Jetpack Compose** und verstehst Zustand, Recomposition und Side Effects – bis zu Animationen, eigenen Layouts, Gesten und adaptiven Layouts.
- Du strukturierst Apps nach **MVVM** und Unidirectional Data Flow mit ViewModel, StateFlow und Repository.
- Du speicherst Daten mit Room und DataStore und sprichst APIs mit Retrofit oder Ktor an.
- Du testest ViewModels, Coroutines und Compose-UI und veröffentlichst signierte Releases.
- Du speicherst Daten mit Room und DataStore, lädst lange Listen mit Paging und sprichst APIs mit Retrofit und OkHttp an, samt Token-Refresh.
- Du testest ViewModels, Coroutines, HTTP, Worker und Compose-UI und veröffentlichst signierte Releases aus einem modularen Build.
- Du liest Compiler-Reports, Traces und Stacktraces, misst mit Macrobenchmark und belegst die Wirkung eines Baseline Profiles.
- Du kannst typische Android-Interviewfragen sicher beantworten.
tracks:
- title: Kotlin – die Sprache
description: Syntax, Typsystem, Funktionen, Collections, Generics und Nebenläufigkeit mit Coroutines und Flow.
modules: [kotlin-grundlagen, null-safety, klassen-objekte, funktionen-lambdas, collections, generics-delegation, coroutines, flow]
- title: Android & Jetpack Compose
description: Plattform-Grundlagen, deklarative Oberflächen, Zustand und Navigation.
modules: [android-grundlagen, compose-grundlagen, compose-state, navigation]
description: Plattform-Grundlagen, deklarative Oberflächen, Zustand, Navigation und fortgeschrittenes Compose.
modules: [android-grundlagen, compose-grundlagen, compose-state, navigation, compose-fortgeschritten]
- title: Architektur, Daten & Qualität
description: Wie professionelle Android-Apps aufgebaut, getestet und ausgeliefert werden.
modules: [architektur, daten-netzwerk, testing, gradle-release]
description: Wie professionelle Android-Apps aufgebaut, getestet, gemessen und ausgeliefert werden.
modules: [architektur, daten-netzwerk, testing, performance-diagnose, performance-messen, gradle-release]
- title: "Praxis: Kotlin mit Bear"
description: 100 Aufgaben aus dem echten Code von Bear – von einzelnen Zeilen bis zu langen Funktionen.
bear: bear/bear-course.json
17 changes: 10 additions & 7 deletions content/kotlin/career.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Rechne je nach Unternehmen mit Screening, technischem Gespräch, Live-Coding ode

Nutze die [Interviewkarten](/kotlin/karten) mit eigenen Beispielen. Eine Antwort ist belastbar, wenn du sie an Code zeigen und eine Gegenfrage beantworten kannst. Auswendig gelernte Definitionen sind nur der Einstieg.

## Zwölf Wochen mit überprüfbarem Ergebnis
## Vierzehn Wochen mit überprüfbarem Ergebnis

Plane pro Woche mehrere kurze aktive Einheiten und einen längeren Praxisblock. Die Tabelle ist ein Vorschlag, keine Garantie für eine bestimmte Lerngeschwindigkeit oder Anstellung. Wiederhole eine Woche, wenn du ihren Nachweis noch nicht selbstständig erbringen kannst.

Expand All @@ -41,12 +41,14 @@ Plane pro Woche mehrere kurze aktive Einheiten und einen längeren Praxisblock.
| 4 | [Coroutines](/kotlin/coroutines), [Flow, StateFlow und SharedFlow](/kotlin/flow) | Abbruch und konkurrierende Zustandsänderung kontrolliert prüfen |
| 5 | [Android-Grundlagen: App, Lebenszyklus, Prozess](/kotlin/android-grundlagen), [Jetpack Compose: Denkmodell, Layouts, Material 3](/kotlin/compose-grundlagen) | Bedienbaren Screen mit großer Schrift und Preview bauen |
| 6 | [Compose State & Side Effects](/kotlin/compose-state), [Navigation mit Compose](/kotlin/navigation) | Editorprojekt mit Wiederherstellung und geprüftem Rückweg |
| 7 | [App-Architektur: MVVM, UDF und Dependency Injection](/kotlin/architektur) | Route, Screen, ViewModel und Repository begründet trennen |
| 8 | [Daten & Netzwerk: Room, DataStore, Retrofit, WorkManager](/kotlin/daten-netzwerk) | Lokale Leseliste und Fake-basierte API-Fehlerbehandlung |
| 9 | [Testing: ViewModels, Coroutines, Room und Compose](/kotlin/testing) | Tests für einen vollständigen Erfolgspfad und zwei Fehlerfälle |
| 10 | [Gradle, Signieren und Release](/kotlin/gradle-release) | CI und installierbares signiertes Test-Release ohne Geheimnisse im Repo |
| 11 | [Praxis: Kotlin mit Bear](/kotlin/bear-01) und Abschlussprojekt | Einen realen Bear-Ablauf erklären; Offline-Abnahme des eigenen Projekts |
| 12 | [Interviewtraining](/kotlin/karten), [Abschlussprojekt](/kotlin/projekte/abschluss-leseliste) | Demo, README, Architekturdiagramm und technisches Probeinterview |
| 7 | [Compose fortgeschritten](/kotlin/compose-fortgeschritten) | Eigenes Layout, eine Animation und ein Zweispaltenlayout ab 600 dp erklären |
| 8 | [App-Architektur: MVVM, UDF, Dependency Injection und Module](/kotlin/architektur) | Route, Screen, ViewModel und Repository begründet trennen; Modulgraph mit `api` und `implementation` zeichnen |
| 9 | [Daten & Netzwerk: Room, Paging, Retrofit, OkHttp, WorkManager](/kotlin/daten-netzwerk) | Lokale Leseliste, Token-Refresh mit Grenze und seitenweise Suche |
| 10 | [Testing: ViewModels, Coroutines, Netzwerk, Worker und Compose](/kotlin/testing) | Tests für einen Erfolgspfad und zwei Fehlerfälle, ein MockWebServer-Test |
| 11 | [Performance & Debugging: Spuren lesen](/kotlin/performance-diagnose), [Performance messen](/kotlin/performance-messen) | Ein Ruckeln mit Trace belegen und beheben; Startzeit mit und ohne Baseline Profile messen |
| 12 | [Gradle, Signieren und Release](/kotlin/gradle-release) | CI mit Qualitätstor, Convention Plugins und signiertes Test-Release ohne Geheimnisse im Repo |
| 13 | [Praxis: Kotlin mit Bear](/kotlin/bear-01) und Abschlussprojekt | Einen realen Bear-Ablauf erklären; Offline-Abnahme des eigenen Projekts |
| 14 | [Interviewtraining](/kotlin/karten), [Abschlussprojekt](/kotlin/projekte/abschluss-leseliste) | Demo, README, Architekturdiagramm, gemessene Startzeit und technisches Probeinterview |

## Offizielle Ressourcen

Expand All @@ -57,3 +59,4 @@ Plane pro Woche mehrere kurze aktive Einheiten und einen längeren Praxisblock.
- [Now in Android](https://github.com/android/nowinandroid): vollständiges offizielles Beispiel zum Lesen und Vergleichen.
- [Android Testing](https://developer.android.com/training/testing): Prüfarten und Werkzeuge.
- [App Signing](https://developer.android.com/studio/publish/app-signing): Signierung und Veröffentlichungsgrundlagen.
- [App performance](https://developer.android.com/topic/performance/overview): Startzeit, Rendering, Baseline Profiles und Messwerkzeuge.
59 changes: 58 additions & 1 deletion content/kotlin/cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,10 @@ try {
| `rememberCoroutineScope` | UI-Coroutine aus Event-Handler starten |
| `DisposableEffect(key)` | Registrieren und in `onDispose` aufräumen |
| `SideEffect` | Zustand nach erfolgreicher Composition veröffentlichen |
| `remember(key) { … }` | Neu rechnen, wenn sich der Key ändert |
| `rememberSaveable(saver = …)` | Eigene Klasse mit `listSaver`/`mapSaver` wiederherstellen |
| `produceState(initial, key)` | Fremde `suspend`-Quelle als State |
| `snapshotFlow { … }` | Compose-State als Flow |

```kotlin
@Composable
Expand All @@ -140,11 +144,58 @@ Draft(value = draft, onChange = { draft = it })
| Route lesen | `entry.toRoute<Detail>()` |
| Zurück | `nav.popBackStack()`; leeren Verlauf vermeiden |
| Doppeltes oberstes Ziel vermeiden | `launchSingleTop = true` |
| Ablauf bündeln | `navigation<Onboarding>(startDestination = Welcome) { … }` |
| Ablauf verlassen | `navigate(Done) { popUpTo<Onboarding> { inclusive = true } }` |
| ViewModel für den Ablauf | `viewModel(nav.getBackStackEntry<Onboarding>())` |
| Ergebnis zurück | `nav.previousBackStackEntry?.savedStateHandle?.set(KEY, wert)` |
| Bereich wechseln | `popUpTo(graph.findStartDestination().id) { saveState = true }`, `launchSingleTop`, `restoreState` |
| Zurück abfangen | `BackHandler(enabled = hatEntwurf) { … }` |
| Datenquelle | Room → Repository → ViewModel → Screen |
| Änderung | UI-Callback → Owner → Repository → neue Daten |
| Dauerhafter Bestand | Room |
| Kleine Einstellungen | DataStore |
| Verschiebbare Hintergrundarbeit | WorkManager; keine exakte Uhrzeitgarantie |
| Relation lesen | `@Embedded` + `@Relation(parentColumns = […], entityColumns = […])`, DAO mit `@Transaction` |
| Fremdschlüssel | `ForeignKey(…)` plus `Index("spalte")` |
| Token anhängen | OkHttp-`Interceptor` mit `newBuilder().header(…)` |
| Token erneuern | `Authenticator`: bei 401, Grenze über `priorResponse`, sonst `null` |
| Lange Listen | `Pager(PagingConfig(pageSize))` → `collectAsLazyPagingItems()`; Netz + Room: `RemoteMediator` |
| Konflikt beim Sync | Version mitschicken; Server gewinnt, Last write wins oder feldweise zusammenführen |

## Compose fortgeschritten

| Aufgabe | API |
| --- | --- |
| Wert animieren | `animateFloatAsState(target, label = …)` |
| Erscheinen/Verschwinden | `AnimatedVisibility(visible) { … }` |
| Inhalt wechseln | `AnimatedContent(state) { shown -> … }` – `shown` benutzen |
| Eigenes Layout | `Layout(content) { ms, cs -> … layout(w, h) { p.placeRelative(x, y) } }` |
| Zeichnen | `Canvas`, `Modifier.drawBehind`, `drawWithCache { onDrawBehind { … } }` |
| Geste | `Modifier.pointerInput(key) { detectTapGestures(…) }` |
| Wert im Teilbaum | `staticCompositionLocalOf { … }`, `CompositionLocalProvider(X provides y)` |
| Fensterbreite | `currentWindowAdaptiveInfo().windowSizeClass.isWidthAtLeastBreakpoint(WIDTH_DP_MEDIUM_LOWER_BOUND)` |
| View einbetten | `AndroidView(factory = { … }, update = { … }, onRelease = { … })` |

## Performance und Debugging

| Frage | Werkzeug |
| --- | --- |
| Warum komponiert das neu? | Compiler-Report (`reportsDestination`), Layout Inspector mit Recomposition-Zählern |
| Instabile Klasse? | `val` statt `var`, UI-Modell, `@Immutable`, `stabilityConfigurationFiles` |
| Wert ändert sich jeden Frame | Lambda-Modifier: `offset { }`, `graphicsLayer { }`, `drawBehind { }` |
| Welcher Frame ruckelt? | System-Trace, Spur „Janky frames“, Perfetto |
| Startzeit | Macrobenchmark mit `StartupTimingMetric`, `ReportDrawnWhen` für TTFD |
| Baseline Profile | `BaselineProfileRule`, `./gradlew :app:generateBaselineProfile`, `None()` gegen `Partial(Require)` |
| Arbeit auf dem Main-Thread | StrictMode im Debug-Build |
| Speicherleck | LeakCanary als `debugImplementation` |
| Absturz im Release | Android vitals, letzte `Caused by`-Zeile, `mapping.txt` |

| Logcat-Abfrage | Bedeutung |
| --- | --- |
| `package:mine` | nur deine App |
| `level:warn` | Warnung und schwerer |
| `-tag:OkHttp` | Tag ausschließen |
| `is:crash` | nur Abstürze |

## Gradle und adb

Expand All @@ -155,9 +206,13 @@ Draft(value = draft, onChange = { draft = it })
./gradlew lintDebug
./gradlew assembleDebug
./gradlew assembleRelease
./gradlew :app:generateBaselineProfile
./gradlew :baselineprofile:connectedBenchmarkReleaseAndroidTest
adb devices
adb install -r app/build/outputs/apk/debug/app-debug.apk
adb logcat
adb logcat -s StrictMode
adb shell am start -W -S app.bear/.MainActivity
```

| Grenze | Beachten |
Expand All @@ -166,7 +221,9 @@ adb logcat
| `assembleRelease` | Signing-Konfiguration und Artefakt prüfen |
| Build-Varianten | Task-Namen hängen vom konkreten Projekt ab |
| Logs / Repository | Keine Tokens, Nutzerdaten oder Signing-Geheimnisse veröffentlichen |
| Mehrere Module | Build-Logik in Convention Plugins (`build-logic`), Wurzel deklariert Fremd-Plugins mit `apply false` |
| `api` oder `implementation` | `implementation` als Standard, `api` nur für Typen der öffentlichen Schnittstelle |

## Offizielle Referenzen

[Kotlin](https://kotlinlang.org/docs/home.html) · [Coroutines](https://kotlinlang.org/docs/coroutines-guide.html) · [Flow](https://kotlinlang.org/docs/flow.html) · [Compose State](https://developer.android.com/develop/ui/compose/state) · [Effekte](https://developer.android.com/develop/ui/compose/side-effects) · [Navigation](https://developer.android.com/guide/navigation/design/type-safety) · [adb](https://developer.android.com/tools/adb)
[Kotlin](https://kotlinlang.org/docs/home.html) · [Coroutines](https://kotlinlang.org/docs/coroutines-guide.html) · [Flow](https://kotlinlang.org/docs/flow.html) · [Compose State](https://developer.android.com/develop/ui/compose/state) · [Effekte](https://developer.android.com/develop/ui/compose/side-effects) · [Navigation](https://developer.android.com/guide/navigation/design/type-safety) · [Paging](https://developer.android.com/topic/libraries/architecture/paging/v3-overview) · [Compose-Performance](https://developer.android.com/develop/ui/compose/performance) · [Baseline Profiles](https://developer.android.com/topic/performance/baselineprofiles/overview) · [Modularisierung](https://developer.android.com/topic/modularization) · [adb](https://developer.android.com/tools/adb)
36 changes: 36 additions & 0 deletions content/kotlin/glossary.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,3 +120,39 @@ terms:
- term: WorkManager
definition: Jetpack-Werkzeug für persistente, verschiebbare Hintergrundarbeit unter Constraints. Es garantiert
keine exakten Uhrzeiten.
- term: Strong Skipping
definition: Standard des Compose-Compilers seit Kotlin 2.0.20. Jede neu startbare Composable ist überspringbar; stabile
Parameter vergleicht Compose mit `equals`, instabile per Identität.
- term: Stabilität
definition: Einstufung eines Typs durch den Compose-Compiler. Stabil heißt, Änderungen bleiben Compose nicht verborgen;
`var`, Java-Typen und Klassen aus Modulen ohne Compose-Compiler gelten als instabil.
- term: CompositionLocal
definition: Wert, den ein Vorfahr für seinen Teilbaum bereitstellt und den Nachfahren über `.current` lesen. Braucht
einen sinnvollen Standardwert; Abhängigkeiten einer Komponente gehören in Parameter.
- term: WindowSizeClass
definition: Einteilung der Fensterbreite und -höhe in Bereiche wie kompakt (unter 600 dp), mittel und erweitert. Grundlage
für adaptive Layouts, unabhängig vom Gerätetyp.
- term: Jank
definition: Ruckeln durch Frames, die ihre Frist verpassen, bei 60 Hz also länger als 16,7 ms brauchen. Im System-Trace
tragen sie einen Jank-Typ wie „App Deadline Missed“.
- term: TTID und TTFD
definition: Time to Initial Display bis zum ersten Frame, Time to Full Display bis zum nutzbaren Inhalt. Die TTFD meldet
die App selbst mit `reportFullyDrawn()` oder `ReportDrawnWhen`.
- term: Baseline Profile
definition: Liste von Klassen und Methoden, die das System bei der Installation vorab kompiliert. Verkürzt Start und
erste Abläufe; erzeugt mit `BaselineProfileRule`, belegt mit Macrobenchmark.
- term: Macrobenchmark
definition: Bibliothek, die die echte App in einem eigenen Prozess wiederholt startet und bedient und daraus Startzeiten
und Frame-Metriken mit Median und Perzentilen berechnet.
- term: Interceptor
definition: Glied in der Kette von OkHttp, das jede Anfrage und Antwort sehen und ändern kann, etwa um ein Token als
Header anzuhängen.
- term: Authenticator
definition: Haken in OkHttp, der nur bei einer 401 aufgerufen wird. Liefert eine neue Anfrage mit erneuerten Zugangsdaten
oder `null`, um aufzugeben.
- term: RemoteMediator
definition: Teil von Paging 3, der Seiten vom Server in die lokale Datenbank lädt, wenn die Liste deren Ende erreicht.
Die Liste selbst liest nur aus der Datenbank.
- term: Convention Plugin
definition: Kleines Gradle-Plugin in einem eingebundenen Build wie `build-logic`, das eine gemeinsame Konvention für
mehrere Module festlegt, etwa Android-Bibliothek oder Hilt.
Loading
Loading