上一篇
安卓开发同时获取网络多个数据
- 行业动态
- 2025-04-21
- 4311
核心思路分析
在安卓开发中同时获取多个网络数据,本质是实现并发网络请求,常见解决方案需满足以下要求:
- 支持多请求并行(非顺序执行)
- 线程安全且不阻塞主线程
- 能统一处理结果和异常
主流实现方案对比
方案 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
Retrofit+RxJava | 需要响应式编程的场景 | 强类型检查、链式调用 | 学习成本较高 |
Retrofit+Coroutine | Kotlin项目优先 | 代码简洁、异常处理方便 | 仅支持Kotlin |
OkHttp+ThreadPool | 纯Java项目或简单需求 | 轻量级、无第三方依赖 | 需手动管理线程 |
Volley+RequestQueue | 图片加载等轻量级请求 | 内置缓存机制 | 不支持流式传输 |
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方案:通过Disposable对象调用dispose()
- 协程方案:通过Job对象调用cancel()
- OkHttp方案:调用Call.cancel()
// RxJava取消示例 private lateinit var disposable: Disposable fun cancelRequest() { disposable.dispose() }
Q2:多个请求结果如何按顺序处理?
A2:
- 使用RxJava的
concatArray
或concatDelayError
保持顺序 - 协程中使用
coroutineScope
保证顺序执行 - 通过自定义调度器控制执行顺序(不推荐)