如何隔离异步请求 实现Android依赖型网络调用可灵活组合
适配该场景的最优解决方案
方案1:Kotlin协程(Android官方首推方案,完美匹配需求)
首先将每个独立的网络请求通过suspendCancellableCoroutine封装为互不依赖的挂起函数,示例如下:
// 独立封装认证请求,可单独调用 suspend fun authenticationRequest(): AuthResult = suspendCancellableCoroutine { cont -> val request = AuthRequest( onSuccess = { result -> cont.resume(result) }, onError = { error -> cont.resumeWithException(error) } ) VolleyRequestQueue.add(request) // 协程取消时同步销毁网络请求,避免内存泄漏 cont.invokeOnCancellation { request.cancel() } } // 独立封装登录请求,可单独调用 suspend fun loginRequest(authResult: AuthResult): LoginResult = suspendCancellableCoroutine { cont -> val request = LoginRequest( params = authResult.token, onSuccess = { result -> cont.resume(result) }, onError = { error -> cont.resumeWithException(error) } ) VolleyRequestQueue.add(request) cont.invokeOnCancellation { request.cancel() } }
在Activity中直接通过生命周期协程域编写线性逻辑,全程不阻塞主线程:
lifecycleScope.launch { try { val authResult = authenticationRequest() // 自动挂起等待结果,不阻塞主线程 val loginResult = loginRequest(authResult) // 前序请求完成后才执行 navigateTo(SomeActivity::class.java) // 自动切换到主线程执行UI操作 } catch (e: Exception) { // 统一处理所有请求的异常 showErrorToast(e.message) } }
该方案优势:
- 所有请求完全独立封装,可单独调用也可自由组合
- 代码为线性逻辑,无回调嵌套,可读性极强
- 自动绑定Activity生命周期,页面销毁时协程自动取消,不会出现观察数据多次触发、内存泄漏等问题
方案2:Java场景可选RxJava实现
如果项目使用Java开发,可将每个请求封装为独立的Single事件,通过flatMap操作符组合依赖关系:
// 独立封装认证请求 public Single<AuthResult> authenticationRequest() { return Single.create(emitter -> { AuthRequest request = new AuthRequest( emitter::onSuccess, emitter::onError ); VolleyRequestQueue.add(request); }); } // 独立封装登录请求 public Single<LoginResult> loginRequest(AuthResult authResult) { return Single.create(emitter -> { LoginRequest request = new LoginRequest( authResult.getToken(), emitter::onSuccess, emitter::onError ); VolleyRequestQueue.add(request); }); }
调用组合逻辑:
authenticationRequest() .flatMap(this::loginRequest) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(loginResult -> { navigateTo(SomeActivity.class); }, error -> { showErrorToast(error.getMessage()); });
使用注意:需将返回的Disposable绑定Activity生命周期,页面销毁时调用dispose()方法取消请求,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Giovanni Laganà
相关产品推荐
相关产品推荐

