xiaohongshu
xiaohongshu
kotlin-android-reviewer
WHEN: Android Kotlin code review, Jetpack Compose patterns, Coroutines/Flow checks, ViewModel structure analysis WHAT: Compose best practices + Coroutines patterns + State management + Memory leak detection + Performance optimization WHEN NOT: KMP shared code → kotlin-multiplatform-reviewer, Back...
Full skill instructions
Reviews Android Kotlin code for Jetpack Compose, Coroutines, Flow, and ViewModel best practices.
build.gradle.ktscom.android.application or com.android.library in build.gradleAndroidManifest.xml existssrc/main/java or src/main/kotlin directories**Kotlin**: 1.9.x
**Compose**: 1.5.x
**minSdk**: 24
**targetSdk**: 34
**Architecture**: MVVM + Clean Architecture
AskUserQuestion:
"Which areas to review?"
Options:
- Full Android pattern check (recommended)
- Jetpack Compose UI patterns
- Coroutines/Flow usage
- ViewModel/State management
- Memory leaks/Performance
multiSelect: true
| Check | Recommendation | Severity |
|---|---|---|
| Side-effect in Composable | Use LaunchedEffect/SideEffect | HIGH |
| Object creation without remember | Use remember { } | HIGH |
| Missing State hoisting | Hoist state to parent | MEDIUM |
| Missing derivedStateOf | Use for derived state | LOW |
| LazyColumn without key | Add key parameter | HIGH |
// BAD: Object creation without remember
@Composable
fun MyScreen() {
val list = mutableListOf<String>() // New every recomposition
}
// GOOD: Use remember
@Composable
fun MyScreen() {
val list = remember { mutableListOf<String>() }
}
// BAD: Direct suspend call in Composable
@Composable
fun MyScreen(viewModel: MyViewModel) {
viewModel.loadData() // Side-effect!
}
// GOOD: Use LaunchedEffect
@Composable
fun MyScreen(viewModel: MyViewModel) {
LaunchedEffect(Unit) {
viewModel.loadData()
}
}
| Check | Recommendation | Severity |
|---|---|---|
| GlobalScope usage | Use viewModelScope/lifecycleScope | CRITICAL |
| Missing Dispatcher | Specify Dispatchers.IO/Default | MEDIUM |
| Missing exception handling | try-catch or CoroutineExceptionHandler | HIGH |
| runBlocking abuse | Convert to suspend function | HIGH |
// BAD: GlobalScope
GlobalScope.launch {
repository.fetchData()
}
// GOOD: viewModelScope
viewModelScope.launch {
repository.fetchData()
}
// BAD: Network on Main
viewModelScope.launch {
val result = api.getData() // NetworkOnMainThreadException
}
// GOOD: IO Dispatcher
viewModelScope.launch {
val result = withContext(Dispatchers.IO) {
api.getData()
}
}
| Check | Recommendation | Severity |
|---|---|---|
| Direct collect in Composable | Use collectAsState | HIGH |
| SharedFlow without replay | Set appropriate replay value | MEDIUM |
| Nullable StateFlow initial | Provide meaningful initial value | MEDIUM |
// BAD: Direct collect in Composable
@Composable
fun MyScreen(viewModel: MyViewModel) {
var data by remember { mutableStateOf<Data?>(null) }
LaunchedEffect(Unit) {
viewModel.dataFlow.collect { data = it }
}
}
// GOOD: collectAsState
@Composable
fun MyScreen(viewModel: MyViewModel) {
val data by viewModel.dataFlow.collectAsState()
}
// BAD: Nullable StateFlow initial
private val _state = MutableStateFlow<UiState?>(null)
// GOOD: Sealed class with clear initial state
private val _state = MutableStateFlow<UiState>(UiState.Loading)
| Check | Issue | Severity |
|---|---|---|
| Direct Context reference | Memory leak risk | CRITICAL |
| View reference | Memory leak risk | CRITICAL |
| Missing SavedStateHandle | Process death handling | MEDIUM |
| Bidirectional data flow | Use UiState + Event pattern | MEDIUM |
// BAD: Activity Context reference
class MyViewModel(private val context: Context) : ViewModel()
// GOOD: Application Context with Hilt
class MyViewModel(
@ApplicationContext private val context: Context
) : ViewModel()
// BAD: Bidirectional binding
class MyViewModel : ViewModel() {
var name = MutableLiveData<String>()
}
// GOOD: Unidirectional + sealed class
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun onNameChanged(name: String) {
_uiState.update { it.copy(name = name) }
}
}
| Check | Problem | Solution |
|---|---|---|
| Inner class with outer reference | Activity leak | WeakReference or static |
| Unremoved Listener | Memory leak | Remove in onDestroy |
| Uncancelled Coroutine Job | Job leak | Structured concurrency |
| Unreleased Bitmap | OOM risk | recycle() or Coil/Glide |
## Android Kotlin Code Review Results
**Project**: [name]
**Kotlin**: 1.9.x | **Compose**: 1.5.x
**Files Analyzed**: X
### Jetpack Compose
| Status | File | Issue |
|--------|------|-------|
| HIGH | ui/HomeScreen.kt | Object creation without remember (line 45) |
| MEDIUM | ui/ProfileScreen.kt | State hoisting recommended |
### Coroutines/Flow
| Status | File | Issue |
|--------|------|-------|
| CRITICAL | data/Repository.kt | GlobalScope usage (line 23) |
| HIGH | viewmodel/MainViewModel.kt | Missing exception handling |
### ViewModel/State
| Status | File | Issue |
|--------|------|-------|
| HIGH | viewmodel/DetailViewModel.kt | Activity Context reference |
### Recommended Actions
1. [ ] GlobalScope → viewModelScope
2. [ ] Add remember { }
3. [ ] Apply UiState sealed class pattern
code-reviewer skill: General Kotlin code qualitykotlin-multiplatform-reviewer skill: KMP shared codetest-generator skill: Android test generationxiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience