栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android Flow遇见Retrofit网络请求实践

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android Flow遇见Retrofit网络请求实践

转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/121754941
本文出自【赵彦军的博客】

文章目录
  • 前言
  • RetrofitFlowCallAdapter
  • 自定义flow 构建类
  • Flow多个请求合并
    • 合并请求 zip
    • 合并请求 combine
  • Flow网络重试 retryWhen

前言

最近项目要从 Rxjava 切到 Flow ,探索最佳实践,于是就有了这篇文章

RetrofitFlowCallAdapter

添加 RetrofitFlowCallAdapter

github地址:https://github.com/zyj1609wz/RetrofitFlowCallAdapter

//添加maven地址
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

//添加依赖
implementation 'com.github.zyj1609wz:RetrofitFlowCallAdapter:1.1.0'

在 Retrofit 初始化的时候加入:

val retrofit = Retrofit.Builder()
        .baseUrl("https://api.github.com")
        .addCallAdapterFactory(FlowCallAdapterFactory.createAsync())
        .addConverterFactory(GsonConverterFactory.create())
        .build()

定义接口

interface ApiService {
    //返回 Body 
    @GET("users/{user}/repos")
    fun listReposWithBody(@Path("user") user: String): Flow>
 
    //返回 Response
    @GET("users/{user}/repos")
    fun listReposWithResponse(@Path("user") user: String): Flow>>
}

创建 ApiService 实例:

 private val service: ApiService = retrofit.create(ApiService::class.java)

使用姿势一:

lifecycleScope.launch {
     service.listReposWithResponse("zyj1609wz")
            .flowOn(Dispatchers.IO)
             .catch {
                 //处理异常
                 it.printStackTrace()
             }
             .collect {
                 //处理结果
                 val list = it.body()
             }
 }

使用姿势二:使用 flow 的 launchIn 函数可以进一步简化

service.listReposWithBody("zyj1609wz")
       .catch {
          //处理异常
          it.printStackTrace()
        }
       .onEach {
          //处理结果
           val item = it[0]   
        }
      .launchIn(lifecycleScope)
      .start()
自定义flow 构建类

首先创建函数的自定义 Flow 构建工具类

fun  getFlow(block: suspend () -> T): kotlinx.coroutines.flow.Flow {
    return flow {
        emit(block())
    }
}

ApiService 的挂起接口声明

interface ApiService {

    @GET("users/{user}/repos")
    suspend fun listReposWithBody(@Path("user") user: String): List
}

使用:

   getFlow {
         service.listReposWithBody("zyj1609wz")
        }
         .catch {
             it.printStackTrace()
          }
         .onEach {
               val item = it[0]
          }
         .launchIn(lifecycleScope)
         .start()
Flow多个请求合并 合并请求 zip
        //第一个网络请求
        val request1 = getFlow {
            service.listReposWithBody("zyj1609wz")
        }

        //第二个网络请求
        val request2 = getFlow {
            service.listReposWithBody("zyj1609wz")
        }

        //两个请求并行
        request1.zip(request2) { response1, response2 ->
            Pair(response1, response2)
        }
            .catch {
                it.printStackTrace()
            }
            .onEach {
                val list1 = it.first
                val list2 = it.second
            }
            .launchIn(lifecycleScope)
            .start()

如果是两个请求合并,那么用 zip 操作符就行了。但是 zip 也有一个问题,只支持两个请求并行。如果是3个请求,或者更多的请求,就需要用到 combine

合并请求 combine
  //第一个网络请求
        val request1 = getFlow {
            service.listReposWithBody("zyj1609wz")
        }

        //第二个网络请求
        val request2 = getFlow {
            service.listReposWithBody("zyj1609wz")
        }

        //第三个网络请求
        val request3 = getFlow {
            service.listReposWithBody("zyj1609wz")
        }

        //3个请求并行
        combine(request1, request2, request3) { response1, response2, response3 ->
            //合并结果
            mutableListOf(response1, response2, response3)
        }
            .catch {
                //处理异常
                it.printStackTrace()
            }
            .onEach {
                //处理结果
            }
            .launchIn(lifecycleScope)
            .start()
Flow网络重试 retryWhen
retryWhen { cause, attempt ->
   //attempt是重试次数,从0开始
   //返回值是 boolean 类型,true 继续重试,false 停止重试
    attempt < 2
}

下面我们写一个重试两次的场景

  getFlow {
            service.listReposWithBody("zyj1609wz")
        }.retryWhen { cause, attempt ->
            attempt < 2
        }.catch {
            //处理异常
        }.onEach {
            //处理结果
        }.launchIn(lifecycleScope)
        .start()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643232.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号