Android(Kotlin)如何重构Volley异步请求实现链式调用与方法复用
Android Kotlin 链式异步Volley请求封装实现方案
完全可以实现你想要的这种异步请求链式调用、全局复用的效果,Kotlin有多种可直接落地的实现方式,以下是两种常用方案:
方案1:高阶函数封装,匹配你期望的链式调用风格
首先封装通用的请求回调包装类,用来承载成功/失败回调逻辑,支持链式调用:
// 通用请求任务包装类 class RequestTask<T> { private var onSuccess: ((T) -> Unit)? = null private var onFailure: ((Exception) -> Unit)? = null fun onSuccess(block: (T) -> Unit): RequestTask<T> { onSuccess = block return this } fun onFailure(block: (Exception) -> Unit): RequestTask<T> { onFailure = block return this } // 供Volley回调触发 internal fun invokeSuccess(result: T) { onSuccess?.invoke(result) } internal fun invokeFailure(error: Exception) { onFailure?.invoke(error) ?: Log.e("RequestError", error.message ?: "unknown error") } }
然后实现全局单例的RequestManager,封装所有公共请求:
object RequestManager { // 封装fooB请求 fun fooB(): RequestTask<Unit> { val task = RequestTask<Unit>() // 执行Volley请求 volleyRequest( onSuccess = { task.invokeSuccess(Unit) }, onFailure = { task.invokeFailure(it) } ) return task } // 封装fooA请求 fun fooA(): RequestTask<Unit> { val task = RequestTask<Unit>() // 执行Volley请求 volleyRequest( onSuccess = { task.invokeSuccess(Unit) }, onFailure = { task.invokeFailure(it) } ) return task } }
在Activity中调用的写法和你期望的几乎一致:
class A : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_A) RequestManager.fooB().onSuccess { RequestManager.fooA().onSuccess { // 在这里执行UI更新操作 } } } }
方案2:Kotlin协程实现(更推荐的Kotlin原生异步方案)
Kotlin协程可以彻底消除回调嵌套,代码逻辑更直观,同样支持全局复用:
首先给Volley请求做挂起函数适配:
suspend fun <T> volleyRequestSuspend(): T = suspendCancellableCoroutine { cont -> volleyRequest( onSuccess = { cont.resume(it) }, onFailure = { cont.resumeWithException(it) } ) }
然后改造RequestManager:
object RequestManager { suspend fun fooB() = volleyRequestSuspend<Unit>() suspend fun fooA() = volleyRequestSuspend<Unit>() }
在Activity中调用的写法更简洁:
class A : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_A) lifecycleScope.launch { runCatching { RequestManager.fooB() RequestManager.fooA() }.onSuccess { // 在这里执行UI更新操作 }.onFailure { Log.e("ERROR", it.message.toString()) } } } }
注意事项
- Volley的
onSuccess默认回调在主线程,可以直接操作UI,如果做了自定义线程切换需要主动切回主线程 - 建议给请求绑定页面生命周期,页面销毁时主动取消未完成的Volley请求,避免内存泄漏和空指针异常
- 通用错误逻辑可以直接封装在
RequestManager中,无需每个调用处重复编写
内容的提问来源于stack exchange,提问作者Giovanni Laganà
相关产品推荐
相关产品推荐

