ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Android app中这样用flow更方便-刷新token获取数据

2021-09-22 23:02:44  阅读:616  来源: 互联网

标签:过期 app flow 接口 重试 获取数据 token 刷新


背景 

        移动app中展示的数据多数都是通过服务器接口获取的,当接口数据与用户相关时,服务端接口会要求客户端把用户信息通过接口发送到服务器。普遍的做法是把用户登录后的token数据发送给服务器的接口。考虑到安全问题,token都有过期时间,token过期后服务端就不能通过这个token查询用户的具体信息了。为了刷新过期token,服务端会提供一个刷新token的接口给客户端使用。

问题分析

  1. 由于要求上传token的服务端接口会有很多,所以这些接口的调用都需要考虑token过期失效问题。
  2. 这些接口调用的异常处理中需要增加token过期处理,在token过期的情况下触发token刷新处理。
  3. token刷新后触发接口的重试请求。

如何使用flow实现

        首先我们实现一个刷新token的flow。

private val refreshTokenFlow = flow {
        if (expiredToken) {
            cachedToken = serverApi.refreshToken("token-0")
            expiredToken = false
        }
        emit(cachedToken)
    }
     expiredToken变量代表token是否过期,实际开发过程中这个变量的值应该根据过期时间计算得出的。cachedToken变量保存着最新的token值,请求用户相关信息的接口时可以把这个token传递给服务端用于查询。我们可以看到cachedToken的值是通过调用服务端提供的刷新接口获取的。这个flow最终发射的是最新的token值,同时我们也看到这个flow调用刷新接口的逻辑只有token过期时才会被调用。

        第二步定义请求用户相关数据的flow

    private fun getDataFlow(token: String) = flow {
        emit(serverApi.getDataViaToken(token))
    }

由于请求用户数据的接口依赖token的值,所以这个flow是通过方法生成的。flow的生成也比较简单,它直接调用服务端的接口并将数据发射出去。

        第三步将刷新token的flow和请求用户数据的flow展开

    private val userDataFlow = refreshTokenFlow.flatMapConcat{token->
        getDataFlow(token)
    }

flatMapConcat方法将前面定义的两个流拼接在一起,这时我们要是收集拼接后的userDataFlow,refreshTokenFlow会被收集,flatMapConcat方法接收到 refreshTokenFlow发射的token后开始收集getDataFlow方法返回的flow。这样连个flow的依赖关系通过flatMapConcat完美实现了。

       第四步实现token过期重试机制 

    private val userDataFlow = refreshTokenFlow.flatMapConcat{token->
        getDataFlow(token)
    }.retryWhen { cause, attempt ->
        if (attempt > 1) {
            false
        } else if(cause is InvalidTokenException) {
            expiredToken = true
            true
        }else{
            false
        }
    }.catch {
        msgView.text = it.message
    }

基于第三步的flow拼接我们添加了retryWhen和cach两个块。retryWhen块用于实现重试机制,参数cause是前面流程发生的异常,参数attempt代表重试的次数,返回值true代表进行重试,返回值false代表不进行重试。在retryWhen块中我们可以通过cause的类型来判断是否要重试,当cause为InvalidTokenException时代表token过期,所以进行重试并且重置了token过期expiredToken。为了避免无限地进行重试,这里限制重试次数为一次。catch块处理不进行重试时的逻辑,一般会将出错的信息显示到界面上。

总结

通过flow的方式实现token刷新机制相较于传统的方式有如下优势:

  1. 逻辑简单明了,刷新流程简单清晰直观。flow操作符语义简单明了,链式的方式声明处理过程更容易理解,没有复杂的嵌套。
  2. 通过声明的方式定义了刷新流程,同时也支持通过声明的方式扩展已有流程。比如这里拼接了刷新token的flow和获取用户数据的flow。
  3. 重试机制可以根据不同的依赖token接口进行定制处理,接口的重试机制更加灵活方便。这里没有针对重试流程定义新的flow,但在实际应用中我们可以为重试流程定义flow,然后将flow拼接在已有flow后。这样我们可以在不同的地方重用重试流程的flow。

标签:过期,app,flow,接口,重试,获取数据,token,刷新
来源: https://blog.csdn.net/mjlong123123/article/details/120423262

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有