home / skills / hoangnguyen0403 / agent-skills-standard / legacy-state
This skill enforces Android legacy state practices by mandating repeatOnLifecycle with StateFlow and viewLifecycleOwner usage to prevent leaks.
npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill legacy-stateReview the files below or copy the command above to add this skill to your agents.
---
name: Android Legacy State
description: Standards for State integration with Views using Coroutines and Lifecycle
metadata:
labels: [android, state, views, lifecycle]
triggers:
files: ['**/*Fragment.kt', '**/*Activity.kt']
keywords: ['repeatOnLifecycle', 'launchWhenStarted']
---
# Android Legacy State Standards
## **Priority: P1**
## Implementation Guidelines
### Flow Consumption
- **Rule**: ALWAYS use `repeatOnLifecycle(Lifecycle.State.STARTED)` to collect flows in Views.
- **Why**: Prevents crashes (collecting while view is destroyed) and saves resources (stops collecting in background).
### LiveData vs Flow
- **New Code**: Use `StateFlow` exclusively.
- **Legacy**: If using LiveData, observe with `viewLifecycleOwner` (Fragment), NOT `this`.
## Anti-Patterns
- **launchWhenX**: `**Deprecated**: Use repeatOnLifecycle.`
- **observe(this)**: `**Leak Risk**: Use viewLifecycleOwner in Fragments.`
## References
- [Flow Consumption Template](references/implementation.md)
This skill defines concise standards for integrating state with Android Views using Kotlin coroutines and the Android lifecycle. It focuses on safe Flow collection, migration guidance from LiveData, and avoiding common anti-patterns that cause leaks or crashes. The goal is predictable, lifecycle-aware UI state handling across Activities and Fragments.
The guidance enforces collecting StateFlow and other Flows inside repeatOnLifecycle(Lifecycle.State.STARTED) so collection automatically starts and stops with the view lifecycle. For legacy LiveData usage, it requires observing with viewLifecycleOwner in Fragments to avoid leaks. It also calls out deprecated and risky patterns like launchWhenX and observe(this) and recommends explicit, lifecycle-aware collection instead.
Why repeatOnLifecycle instead of launchWhenStarted?
repeatOnLifecycle creates a new coroutine in the lifecycleScope and cancels it automatically on stop, avoiding subtle race conditions and ensuring collection restarts reliably.
Can I keep using LiveData?
Legacy LiveData is allowed but observe with viewLifecycleOwner in Fragments. Prefer StateFlow for new code for clearer semantics with coroutines.