K
Kotlin Android 代码审查
作者:鹿Sir开发工具v1
审查 Android Kotlin 代码的 Jetpack Compose、Coroutines/Flow、ViewModel 与内存泄漏问题,按严重程度输出分级检查报告与整改清单。做 Android 项目代码评审、排查内存泄漏、优化重组性能、规范协程与状态管理时使用。当用户提到 Compose 模式、协程、Flow、ViewModel、Android 内存泄漏、Kotlin 代码审查时触发。触发词:Android、Kotlin、Compose、协程、ViewModel、内存泄漏、代码审查。
下载量
400
点赞
99
价格
免费
技能文档
---
name: majiayu000-kotlin-android-reviewer
title: Kotlin Android 代码审查
category: 开发工具
description: 审查 Android Kotlin 代码的 Jetpack Compose、Coroutines/Flow、ViewModel 与内存泄漏问题,按严重程度输出分级检查报告与整改清单。做 Android 项目代码评审、排查内存泄漏、优化重组性能、规范协程与状态管理时使用。当用户提到 Compose 模式、协程、Flow、ViewModel、Android 内存泄漏、Kotlin 代码审查时触发。触发词:Android、Kotlin、Compose、协程、ViewModel、内存泄漏、代码审查。
---
# Kotlin Android 代码审查
审查 Android Kotlin 代码中 Jetpack Compose、Coroutines、Flow、ViewModel 的最佳实践合规性。
## 适用场景
- Android Kotlin 项目代码评审
- 用户提到「Compose 模式」「协程」「Flow」「ViewModel」
- Android 性能排查与内存泄漏检查
- `build.gradle.kts` 含 Android 插件的项目
## 项目识别
满足任一即视为 Android 项目:
- `build.gradle` 中有 `com.android.application` 或 `com.android.library`
- 存在 `AndroidManifest.xml`
- 存在 `src/main/java` 或 `src/main/kotlin` 目录
## 技能工作流
### 步骤1:分析项目
先摸清项目技术栈基线:
```text
**Kotlin**: 1.9.x
**Compose**: 1.5.x
**minSdk**: 24
**targetSdk**: 34
**架构**: MVVM + Clean Architecture
```
### 步骤2:确定审查范围
询问用户要审查哪些方面(可多选):
- Android 全量模式检查(推荐)
- Jetpack Compose UI 模式
- Coroutines/Flow 用法
- ViewModel/状态管理
- 内存泄漏/性能
### 步骤3:按规则逐项检查
**Jetpack Compose 模式**
| 检查项 | 建议 | 严重度 |
|-------|----------------|----------|
| Composable 内副作用 | 用 LaunchedEffect/SideEffect | HIGH |
| 未用 remember 创建对象 | 用 remember { } | HIGH |
| 缺少状态上提(State hoisting) | 把状态上提到父级 | MEDIUM |
| 缺少 derivedStateOf | 派生状态用 derivedStateOf | LOW |
| LazyColumn 未设 key | 补 key 参数 | HIGH |
```kotlin
// BAD: 未用 remember 创建对象
@Composable
fun MyScreen() {
val list = mutableListOf<String>() // 每次重组都新建
}
// GOOD: 使用 remember
@Composable
fun MyScreen() {
val list = remember { mutableListOf<String>() }
}
// BAD: Composable 内直接调 suspend
@Composable
fun MyScreen(viewModel: MyViewModel) {
viewModel.loadData() // 副作用!
}
// GOOD: 用 LaunchedEffect
@Composable
fun MyScreen(viewModel: MyViewModel) {
LaunchedEffect(Unit) {
viewModel.loadData()
}
}
```
**协程模式**
| 检查项 | 建议 | 严重度 |
|-------|----------------|----------|
| 使用 GlobalScope | 改用 viewModelScope/lifecycleScope | CRITICAL |
| 未指定调度器 | 明确 Dispatchers.IO/Default | MEDIUM |
| 缺少异常处理 | try-catch 或 CoroutineExceptionHandler | HIGH |
| 滥用 runBlocking | 改为 suspend 函数 | HIGH |
```kotlin
// BAD: GlobalScope
GlobalScope.launch {
repository.fetchData()
}
// GOOD: viewModelScope
viewModelScope.launch {
repository.fetchData()
}
// BAD: 主线程做网络请求
viewModelScope.launch {
val result = api.getData() // NetworkOnMainThreadException
}
// GOOD: IO 调度器
viewModelScope.launch {
val result = withContext(Dispatchers.IO) {
api.getData()
}
}
```
**Flow 模式**
| 检查项 | 建议 | 严重度 |
|-------|----------------|----------|
| Composable 内直接 collect | 用 collectAsState | HIGH |
| SharedFlow 未设 replay | 设置合适的 replay 值 | MEDIUM |
| StateFlow 初始值为 null | 提供有意义的初始值 | MEDIUM |
```kotlin
// BAD: Composable 内直接 collect
@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: 可空 StateFlow 初始值
private val _state = MutableStateFlow<UiState?>(null)
// GOOD: 密封类 + 明确初始状态
private val _state = MutableStateFlow<UiState>(UiState.Loading)
```
**ViewModel 模式**
| 检查项 | 问题 | 严重度 |
|-------|----------------|----------|
| 直接持有 Context | 内存泄漏风险 | CRITICAL |
| 持有 View 引用 | 内存泄漏风险 | CRITICAL |
| 缺少 SavedStateHandle | 进程被杀后状态丢失 | MEDIUM |
| 双向数据流 | 改用 UiState + Event 模式 | MEDIUM |
```kotlin
// BAD: 持有 Activity Context
class MyViewModel(private val context: Context) : ViewModel()
// GOOD: 用 Hilt 注入 Application Context
class MyViewModel(
@ApplicationContext private val context: Context
) : ViewModel()
// BAD: 双向绑定
class MyViewModel : ViewModel() {
var name = MutableLiveData<String>()
}
// GOOD: 单向数据流 + 密封类
class MyViewModel : ViewModel() {
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
fun onNameChanged(name: String) {
_uiState.update { it.copy(name = name) }
}
}
```
**内存泄漏检测**
| 检查项 | 问题 | 解决方案 |
|---------|----------|
| 内部类持有外部引用 | Activity 泄漏 | WeakReference 或改静态 |
| 监听器未注销 | 内存泄漏 | onDestroy 中移除 |
| 协程 Job 未取消 | Job 泄漏 | 结构化并发 |
| Bitmap 未释放 | OOM 风险 | recycle() 或改用 Coil/Glide |
### 步骤4:输出审查报告
```text
## Android Kotlin 代码审查结果
**项目**: [名称]
**Kotlin**: 1.9.x | **Compose**: 1.5.x
**分析文件数**: X
### Jetpack Compose
| 级别 | 文件 | 问题 |
|--------|------|-------|
| HIGH | ui/HomeScreen.kt | 未用 remember 创建对象(第 45 行) |
| MEDIUM | ui/ProfileScreen.kt | 建议状态上提 |
### Coroutines/Flow
| 级别 | 文件 | 问题 |
|--------|------|-------|
| CRITICAL | data/Repository.kt | 使用了 GlobalScope(第 23 行) |
| HIGH | viewmodel/MainViewModel.kt | 缺少异常处理 |
### ViewModel/状态
| 级别 | 文件 | 问题 |
|--------|------|-------|
| HIGH | viewmodel/DetailViewModel.kt | 持有 Activity Context |
### 整改清单
1. [ ] GlobalScope → viewModelScope
2. [ ] 补充 remember { }
3. [ ] 应用 UiState 密封类模式
```
## 最佳实践要点
1. **Compose**:优先无状态 Composable,做好状态上提
2. **协程**:结构化并发,选对调度器
3. **Flow**:区分热/冷流,UI 状态用 StateFlow
4. **ViewModel**:单向数据流,避免持有 Context
5. **测试**:Flow 用 Turbine,Compose 用测试规则
## 附注
- 基于 Compose 1.0+ 规则
- 建议 Kotlin 1.9+、Coroutines 1.7+
- 兼容 Hilt/Dagger 依赖注入模式使用说明
# Kotlin Android 代码审查 审查 Android Kotlin 项目的 Compose、协程/Flow、ViewModel 用法与内存泄漏,输出分级报告与整改清单。 ## 使用 ```text 帮我审查这个 Android 项目的 Compose 和协程用法 ``` ```text 排查 App 内存泄漏,重点看 ViewModel 和监听器 ``` ## 工作原理 先识别 Android 项目(build.gradle 插件、Manifest、源码目录),确认 Kotlin/Compose 版本基线,再按五大类 20+ 条规则逐项检查:Compose 副作用与重组性能、协程作用域与调度器、Flow 收集方式、ViewModel 状态管理模式、常见内存泄漏点,按 CRITICAL/HIGH/MEDIUM 分级输出问题表与整改清单。
支持平台:Qoder · QoderWork · Claude · Codex 等 AI 编程助手