核心思路分析
在安卓开发中同时获取多个网络数据,本质是实现并发网络请求,常见解决方案需满足以下要求:
Retrofit+RxJava实现方案(以双请求为例)
// 1. 添加依赖 implementation "com.squareup.retrofit2:retrofit:2.9.0" implementation "com.squareup.retrofit2:adapter-rxjava2:2.9.0" implementation "io.reactivex.rxjava2:rxjava:2.2.21" implementation "io.reactivex.rxjava2:rxandroid:2.1.1" // 2. 定义API接口 interface ApiService { @GET("path1") fun request1(): Single<Response1> @GET("path2") fun request2(): Single<Response2> } // 3. 创建Retrofit实例 val apiService = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build() .create(ApiService::class.java) // 4. 合并请求 val combinedSingle = Single.zip( apiService.request1(), apiService.request2(), BiFunction { response1, response2 -> CombinedResponse(response1, response2) } ) // 5. 订阅请求 combinedSingle.subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe({ result -> // 处理成功结果 }, { error -> // 处理错误 })
Kotlin协程实现方案
// 1. 添加依赖 implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0" // 2. 挂起函数封装 suspend fun fetchData(): CombinedResponse { return coroutineScope { val response1 = async { apiService.request1().execute() } val response2 = async { apiService.request2().execute() } CombinedResponse(response1.body(), response2.body()) } } // 3. 在ViewModel中调用 viewModelScope.launch { try { val result = fetchData() // 更新UI } catch (e: Exception) { // 处理异常 } }
关键注意事项
- 线程管理:确保网络请求在IO线程执行,结果回调在主线程
- 生命周期感知:使用ViewModel+LiveData或LifecycleObserver防止内存泄漏
- 错误处理:需统一处理网络错误、数据解析错误、超时等情况
- 资源释放:及时关闭OkHttp响应体,避免内存泄漏
相关问题与解答
Q1:如何取消未完成的网络请求?
A1:
// RxJava取消示例
private lateinit var disposable: Disposable
fun cancelRequest() {
disposable.dispose()
}
Q2:多个请求结果如何按顺序处理?
A2:
- 使用RxJava的
concatArray
或concatDelayError
保持顺序 - 协程中使用
coroutineScope
保证顺序执行 - 通过自定义调度器控制执行顺序(不推荐)