android-coroutines by new-silvermoon/awesome-android-agent-skills
npx skills add https://github.com/new-silvermoon/awesome-android-agent-skills --skill android-coroutines此技能提供编写符合生产质量标准的 Android Kotlin 协程代码的权威规则和模式。它强制执行结构化并发、生命周期安全性和现代最佳实践(2025 年标准)。
Flow、StateFlow、SharedFlow 和 callbackFlow。viewModelScope、lifecycleScope)和安全收集(repeatOnLifecycle)。CoroutineExceptionHandler、 和正确的 层次结构。广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
SupervisorJobtry-catchensureActive() 确保长时间运行的操作是协作式的。TestDispatcher 和 runTest。当用户要求以下操作时,激活此技能:
切勿 在类内部硬编码调度器(例如 Dispatchers.IO、Dispatchers.Default)。
始终 通过构造函数注入 CoroutineDispatcher。
默认 在构造函数参数中使用 Dispatchers.IO 以便利,但允许其被覆盖。
// 正确
class UserRepository(
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) { ... }
// 错误
class UserRepository {
fun getData() = withContext(Dispatchers.IO) { ... }
}
suspend 函数公开。Flow 公开。Dispatchers.Main 调用它们而不会阻塞 UI。withContext(dispatcher) 将执行移至后台。切勿 直接在 lifecycleScope.launch 或 launchWhenStarted(已弃用/不安全)中收集流。
始终 在 Activity 或 Fragment 中收集流时使用 repeatOnLifecycle(Lifecycle.State.STARTED)。
// 正确
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { ... }
}
}
viewModelScope。StateFlow 或 SharedFlow。MutableStateFlow 或 MutableSharedFlow。.asStateFlow() 或向上转型将它们作为只读的 StateFlow 或 Flow 暴露。GlobalScope。它会破坏结构化并发并导致泄漏。applicationScope(一个与 Application 生命周期绑定的自定义作用域)。catch (e: Exception) 块中捕获 CancellationException。CancellationException 时才使用 runCatching。launch 内部)中使用 CoroutineExceptionHandler。它在 async 或子协程内部无效。ensureActive() 或 yield() 来检查取消状态。delay() 和 withContext() 这样的标准函数已经是可取消的。callbackFlow 将基于回调的 API 转换为 Flow。callbackFlow 块的末尾使用 awaitClose 来注销监听器。class NewsRepository(
private val remoteDataSource: NewsRemoteDataSource,
private val externalScope: CoroutineScope, // 用于应用范围内的事件
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
val newsUpdates: Flow<List<News>> = flow {
val news = remoteDataSource.fetchLatestNews()
emit(news)
}.flowOn(ioDispatcher) // 上游在 IO 调度器上执行
}
suspend fun loadDashboardData() = coroutineScope {
val userDeferred = async { userRepo.getUser() }
val feedDeferred = async { feedRepo.getFeed() }
// 等待两者完成
DashboardData(
user = userDeferred.await(),
feed = feedDeferred.await()
)
}
@Test
fun testViewModel() = runTest {
val testDispatcher = StandardTestDispatcher(testScheduler)
val viewModel = MyViewModel(testDispatcher)
viewModel.loadData()
advanceUntilIdle() // 处理协程
assertEquals(expectedState, viewModel.uiState.value)
}
每周安装量
161
代码仓库
GitHub 星标数
565
首次出现
2026 年 1 月 27 日
安全审计
安装于
opencode145
codex144
claude-code115
gemini-cli112
github-copilot108
kimi-cli103
This skill provides authoritative rules and patterns for writing production-quality Kotlin Coroutines code on Android. It enforces structured concurrency, lifecycle safety, and modern best practices (2025 standards).
Flow, StateFlow, SharedFlow, and callbackFlow.viewModelScope, lifecycleScope) and safe collection (repeatOnLifecycle).CoroutineExceptionHandler, SupervisorJob, and proper try-catch hierarchies.ensureActive().TestDispatcher and runTest.Activate this skill when the user asks to:
NEVER hardcode Dispatchers (e.g., Dispatchers.IO, Dispatchers.Default) inside classes.
ALWAYS inject a CoroutineDispatcher via the constructor.
DEFAULT to Dispatchers.IO in the constructor argument for convenience, but allow it to be overridden.
// CORRECT class UserRepository( private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO ) { ... }
// INCORRECT class UserRepository { fun getData() = withContext(Dispatchers.IO) { ... } }
suspend functions.Flow.Dispatchers.Main without blocking the UI.withContext(dispatcher) inside the repository implementation to move execution to the background.NEVER collect a flow directly in lifecycleScope.launch or launchWhenStarted (deprecated/unsafe).
ALWAYS use repeatOnLifecycle(Lifecycle.State.STARTED) for collecting flows in Activities or Fragments.
// CORRECT viewLifecycleOwner.lifecycleScope.launch { viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { viewModel.uiState.collect { ... } } }
viewModelScope for initiating coroutines in ViewModels.StateFlow or SharedFlow that the View observes.MutableStateFlow or MutableSharedFlow publicly.StateFlow or Flow using .asStateFlow() or upcasting.GlobalScope. It breaks structured concurrency and leads to leaks.applicationScope (a custom scope tied to the Application lifecycle).CancellationException in a generic catch (e: Exception) block without rethrowing it.runCatching only if you explicitly rethrow CancellationException.CoroutineExceptionHandler only for top-level coroutines (inside launch). It has no effect inside async or child coroutines.ensureActive() or yield() in tight loops (e.g., processing a large list, reading files) to check for cancellation.delay() and withContext() are already cancellable.callbackFlow to convert callback-based APIs to Flow.awaitClose at the end of the callbackFlow block to unregister listeners.class NewsRepository(
private val remoteDataSource: NewsRemoteDataSource,
private val externalScope: CoroutineScope, // For app-wide events
private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO
) {
val newsUpdates: Flow<List<News>> = flow {
val news = remoteDataSource.fetchLatestNews()
emit(news)
}.flowOn(ioDispatcher) // Upstream executes on IO
}
suspend fun loadDashboardData() = coroutineScope {
val userDeferred = async { userRepo.getUser() }
val feedDeferred = async { feedRepo.getFeed() }
// Wait for both
DashboardData(
user = userDeferred.await(),
feed = feedDeferred.await()
)
}
@Test
fun testViewModel() = runTest {
val testDispatcher = StandardTestDispatcher(testScheduler)
val viewModel = MyViewModel(testDispatcher)
viewModel.loadData()
advanceUntilIdle() // Process coroutines
assertEquals(expectedState, viewModel.uiState.value)
}
Weekly Installs
161
Repository
GitHub Stars
565
First Seen
Jan 27, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode145
codex144
claude-code115
gemini-cli112
github-copilot108
kimi-cli103
Next.js 15+ 最佳实践指南:文件约定、RSC边界、异步模式与性能优化
989 周安装
GCP开发最佳实践指南:Terraform、Cloud Functions、Cloud Run、Firestore与BigQuery
159 周安装
从AI工作流中移除技能指南 - 清理未使用或弃用技能完整教程
159 周安装
Hyvä Playwright 测试指南:解决 Alpine.js 冲突,编写可靠电商自动化测试
159 周安装
Clojure开发技能:REPL驱动开发与函数式编程最佳实践指南
159 周安装
FFmpeg 视频音频处理最佳实践 | 转码、剪辑、滤镜全攻略
159 周安装
数据库迁移指南:跨ORM(Sequelize/TypeORM/Prisma)模式转换与零停机部署
159 周安装