查看原文
其他

如何优雅地管理Retrofit请求的生命周期

andydev 鸿洋 2019-04-05

每日推荐


 [编译Android下可执行命令的FFmpeg]

 http://blog.csdn.net/mabeijianxi/article/details/72904694


本文使用两种方式编译可以在Android下执行命令的FFmpeg,一种是传统的ndk-build工具,一种是cmake工具,经过我的项目实战,非常推荐cmake,因为AS 2.2以后对它支持的非常好,你可以非常方便的像debug Java代码一样去debug Native代码。


本文作者


本文由andydev投稿。

andydev的博客地址:

http://andydev.me/2017/07/03/retrofit-lifecycle-management/


1
问题背景


Retrofit大家都不陌生,一般情况下,我们都会在组件(Actvity, Fragment)生命周期结束的时候去cancel掉网络请求。这样做当然无可厚非,但是有一点麻烦的是,要定义一个变量来引用这个Call,网络请求少的情况下还好,假如一个类中有很多Call时候呢?


单是要给Call命名都让我头大了…


2
解决思路


可能最容易想到的就是:在Activity中定义一个集合来保存所有的Call,在onDestroy的时候遍历所有Call,调用cancel方法。


这个方案虽然能达到效果,但是每次都要手动把Call add到集合中,不仅繁琐而且还可能会忘


后来有一位小伙伴为了解决上面提到的缺陷,自己定义了一个类,代码大概如下:



使用的时候将Call和Callback作为参数传进去即可。


额…怎么说呢,这样确实能解决上面所提到的缺陷,只不过这样的调用方式与开发者原来的习惯不同,看起来很别扭。


OK,我们还是直接步入正轨吧…



其实我们想做的就是在Call请求执行前,将其加入到集合中,但是又不想打破原有的调用习惯。那为何不试试代理模式呢?


假设有接口 UserAPI.java 如下:




我们定义一个 UserAPI.java 的静态代理类 UserAPIInvokeProxy.java



使用的时候,将Retrofit所创建的接口实例作为参数传入,让我们的代理类对其进行代理,之后所有的调用都通过代理类来完成。


可能有小伙伴要怼我了。调用习惯是保持一致了,但是这代码量还不如直接用上面2种方案呢… 而且每新增一个方法,都要对代理类进行改动,真的好蠢。


别开枪…我有办法。


对于这种机械式的代码,就应该考虑让编译时注解来解放你双手了!


是不是想到了Butterknife了?


没错,我们要编写一个编译时注解来帮我们完成这种机械式的代码。


最终达到的效果是:


只要在 UserAPI.java 中用 @RetrofitInterface 表示这个类需要生成代理类,就会在build的时候自动生成代理类 UserAPIInvokeProxy.java



然而,这篇文章并不会讲如何编写编译时注解,因为不在范畴内。本文的目的主要是想分享下问题的解决思路。


可参考我之前推送的一篇文章:Android 如何编写基于编译时注解的项目


如果对 RetrofitInterface 的解析器源码感兴趣的话,可以点这里传送门:


java/me/andydev/retrofit/lifecycle/compiler/RetrofitProcessor.java


当然我也封装成了一个库,想直接使用的小伙伴可以按照如下指引:


https://github.com/luckyandyzhang/RetrofitLifecycle


小结


其实很多时候,我们会避重就轻,习惯性地忽略比较复杂的解决方案,这是人之常情。只是当你尝试了多种方案还没有结果的时候,不要忘记了这种复杂方

案本来的可行性。


另外,设计模式是一门必修课,它能在你解决问题的时候给你一种思路,让你不会走太多弯路。


如果你有想学习的文章直接留言,我会整理征稿。如果你有好的文章想和大家分享欢迎投稿,直接向我投递文章链接即可。


欢迎长按下图->识别图中二维码或者扫一扫关注我的公众号:

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存