现代Android开发:轻量级协程框架设计与实践

一、框架设计理念

本框架专为Android应用项目设计,遵循以下核心原则:

  1. ​简洁易用​​:提供直观的API,降低学习成本
  2. ​生命周期感知​​:深度整合ViewModel和Lifecycle组件
  3. ​安全可靠​​:内置完善的异常处理机制
  4. ​性能优化​​:提供合理的线程调度和资源管理策略

二、轻量级协程框架实现

2.1 基础架构设计

class CoroutineFramework(private val config: Config = Config()) {
    data class Config(
        val defaultDispatcher: CoroutineDispatcher = Dispatchers.IO,
        val defaultErrorHandler: (Throwable) -> Unit = { e ->
            Log.e("CoroutineFramework", "Global error", e)
        }
    )

    fun <T> safeLaunch(
        scope: CoroutineScope,
        dispatcher: CoroutineDispatcher = config.defaultDispatcher,
        errorHandler: (Throwable) -> Unit = config.defaultErrorHandler,
        block: suspend CoroutineScope.() -> T
    ): Job {
        return scope.launch(dispatcher + CoroutineExceptionHandler { _, e ->
            errorHandler(e)
        }) {
            block()
        }
    }

    fun <T> ViewModel.safeLaunch(
        dispatcher: CoroutineDispatcher = config.defaultDispatcher,
        errorHandler: (Throwable) -> Unit = config.defaultErrorHandler,
        block: suspend CoroutineScope.() -> T
    ): Job {
        return safeLaunch(viewModelScope, dispatcher, errorHandler, block)
    }
}

2.2 核心功能模块

网络请求封装
suspend fun <T> requestWithState(
    scope: CoroutineScope,
    stateFlow: MutableStateFlow<UiState<T>>,
    request: suspend () -> T
): Job {
    return scope.safeLaunch {
        stateFlow.value = UiState.Loading
        try {
            val result = withContext(Dispatchers.IO) { request() }
            stateFlow.value = UiState.Success(result)
        } catch (e: Exception) {
            stateFlow.value = UiState.Error(e)
        }
    }
}
智能重试机制
suspend fun <T> retryable(
    times: Int = 3,
    initialDelay: Long = 1000,
    maxDelay: Long = 10000,
    factor: Double = 2.0,
    shouldRetry: (Throwable) -> Boolean = { it.isRetryable() },
    block: suspend () -> T
): T {
    var currentDelay = initialDelay
    repeat(times - 1) {
        try {
            return block()
        } catch (e: Exception) {
            if (!shouldRetry(e)) throw e
            delay(currentDelay)
            currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
        }
    }
    return block()
}

private fun Throwable.isRetryable(): Boolean {
    return this is IOException || this is TimeoutException
}
Flow增强
fun <T> Flow<T>.collectSafely(
    scope: CoroutineScope,
    onEach: (T) -> Unit,
    onError: (Throwable) -> Unit = { e ->
        Log.e("FlowError", "Collect error", e)
    },
    onComplete: () -> Unit = {}
): Job {
    return scope.safeLaunch {
        this@collectSafely
            .catch { onError(it) }
            .onCompletion { onComplete() }
            .collect { onEach(it) }
    }
}

三、框架使用指南

3.1 基础使用

val coroutineFramework = CoroutineFramework()

class MyViewModel : ViewModel() {
    private val _data = MutableStateFlow<UiState<String>>(UiState.Idle)
    val data: StateFlow<UiState<String>> = _data

    fun fetchData() {
        coroutineFramework.safeLaunch(viewModelScope) {
            _data.value = UiState.Loading
            val result = retryable { apiService.getData() }
            _data.value = UiState.Success(result)
        }
    }
}

3.2 高级场景

并行请求
suspend fun fetchUserAndPosts(userId: String): Pair<User, List<Post>> {
    return coroutineScope {
        val userDeferred = async { userRepository.getUser(userId) }
        val postsDeferred = async { postRepository.getPosts(userId) }
        userDeferred.await() to postsDeferred.await()
    }
}
带超时的操作
fun uploadFileWithProgress(file: File) {
    coroutineFramework.safeLaunch(viewModelScope) {
        val result = withTimeoutOrNull(30_000) {
            fileUploader.upload(file) { progress ->
                _uploadProgress.value = progress
            }
        }
        _uploadResult.value = result ?: throw TimeoutException()
    }
}

四、性能优化建议

  1. ​线程池优化​​:

    val customDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
  2. ​Flow背压处理​​:

    flow.buffer(10)
        .conflate()
  3. ​内存泄漏防护​​:

    class MyFragment : Fragment() {
        private val job = Job()
        private val scope = CoroutineScope(Dispatchers.Main + job)
    
        override fun onDestroy() {
            super.onDestroy()
            job.cancel()
        }
    }

五、框架扩展点

自定义异常处理

val framework = CoroutineFramework(
    Config(
        defaultErrorHandler = { e ->
            when (e) {
                is NetworkException -> showNetworkError()
                is ServerException -> showServerError()
                else -> showGenericError()
            }
        }
    )
)

日志监控

class CoroutineMonitor : AbstractCoroutineContextElement(CoroutineMonitor) {
    companion object Key : CoroutineContext.Key<CoroutineMonitor>

    override fun <T> interceptContinuation(continuation: Continuation<T>) =
        MonitoringContinuation(continuation)
}

// 使用示例
scope.launch(Dispatchers.IO + CoroutineMonitor()) { ... }

六、最佳实践总结

  1. ​ViewModel中使用​​:

    • 始终使用viewModelScope
    • 通过StateFlow管理UI状态
    • 将复杂业务逻辑拆分为多个suspend函数
  2. ​UI层调用​​:

    lifecycleScope.launchWhenStarted {
        viewModel.data.collect { state ->
            when (state) {
                is UiState.Loading -> showLoading()
                is UiState.Success -> showData(state.data)
                is UiState.Error -> showError(state.error)
            }
        }
    }
  3. ​单元测试​​:

    @ExperimentalCoroutinesApi
    class MyViewModelTest {
        @get:Rule
        val coroutineRule = MainCoroutineRule()
    
        @Test
        fun testDataLoading() = runTest {
            val viewModel = MyViewModel()
            viewModel.fetchData()
            advanceUntilIdle()
            assertEquals(expectedData, viewModel.data.value)
        }
    }

本框架经过精心设计,适用于大多数Android应用项目,平衡了功能丰富性和使用简便性。开发者可以根据项目需求灵活选择使用基础功能或高级特性,逐步提升项目的协程使用水平。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追随远方

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值