Android 网络框架:Retrofit2一篇就够了(2020-4-23)

前言

 目前Retrofit2、RxJava2、OkHttp3可以说非常火,经常被一并提及,因此学习它们是非常有必要的。
 本系列主要写Retrofit2的使用,Retrofit2其实并不复杂,使用它只是为了规范我们网络请求的代码,深入学习之后会发现Retrofit2可以让代码可读性更好。
 Retrofit的特点就是使用注解来描述一个http请求,本系列会在下一章具体讲解每一个注解的使用。
 retrofit官网地址:https://square.github.io/retrofit/


1 入门

 GRADLE

implementation 'com.squareup.retrofit2:retrofit:2.4.0'

 也可以在官网下载JAR包,GitHub上可以查看源代码和示例

 ①创建实体类接收Json。

data class WordData constructor(var reason:String,var result:Any,var error_code:String)

 ②将HTTP API转换成接口,如下所示:

interface WordService{
    @GET("query")
    fun getWord(@Query("word") word: String, @Query("dtype") dtype: String,@Query("key") key: String): Call<WordData>    
}

 ③生成Retrofit实现接口实例。

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

 var wordService = retrofit.create(WordService::class.java)

 ④调用接口的方法去异步请求网络,并通过callback回调请求结果。
  (示例使用的是聚合数据的免费接口,key是错误的,正确key的Json太长....)

 wordService.getWord("你","json","c5c6a09be5cdb2047")
    .enqueue(object : Callback<WordData> {
    override fun onFailure(call: Call<WordData>, t: Throwable) {
        Log.d(tag,"onFailure")
    }
    override fun onResponse(call: Call<WordData>, response: Response<WordData>) {
        Log.d(tag,response.body().toString())
    }
 })

 请求回来的数据如下所示:

 WordData(reason=错误的请求KEY, result=null, error_code=10001)

 至此,已经使用Retrofit完成一个网络请求。
 你也可以通过call调用同步网络请求代码如下所示:

 var wordService = wordService.getWord("你","json","c5c6a09be5cdb2047")
 var wordData = wordService.execute().body() as WordData

2 Converters

 retrofit可以配置不同的工具来解析数据,例如gson、xml等等。

  • Gson: com.squareup.retrofit2:converter-gson
  • Simple XML: com.squareup.retrofit2:converter-simplexml

 示例代码如下所示:

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .build()

 通过调用addConverterFactory()方法,添加GsonConverterFactory。


3 OkHttpClient

 Retrofit也可以自定义OkHttpClient,代码如下所示:

 val dispatcher = Dispatcher(Executors.newFixedThreadPool(20))
        dispatcher.setMaxRequests(20)
        dispatcher.setMaxRequestsPerHost(1)

 val okHttpClient = OkHttpClient.Builder()
            .dispatcher(dispatcher)
            .connectionPool(ConnectionPool(100, 30, TimeUnit.SECONDS))
            .build()

 var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn/xhzd/")
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build()

4 Retrofit2 + RxJava2

 在Retrofit中使用RxJava2,接口的定义和网络请求和上面略有不同,而且需要调用addCallAdapterFactory添加对RxJava2的支持。

Retrofit2

implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0'

Rxjava2

implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'

①将HTTP API转换成接口,但是返回参数需要改变成Observable<WordData>,如下所示:

interface WordService {
    @GET("/xhzd/query")
    fun getWord(@Query("word") word: String, @Query("dtype") dtype: String,@Query("key") key: String): Observable<WordData>
}

②调用addCallAdapterFactory方法传入RxJava2CallAdapterFactory.create()生成Retrofit,然后实现接口实例。

var retrofit = Retrofit.Builder()
            .baseUrl("http://v.juhe.cn")
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
            .client(okHttpClient)
            .build()
var wordService = retrofit.create(WordService::class.java)

③使用RxJava2对数据进行处理,代码如下所示:

wordService.getWord("你", "json", "c5c6a09be5cdb2047")
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe({
                    Log.d(tag, it.toString())
                }, {
                    Log.d(tag, "onFailure")
                })

可以看见日志输入如下所示:

WordData(reason=错误的请求KEY, result=null, error_code=10001)

5 高级写法

①首先使用Body定义Api

interface IApi {
        @POST("/xhzd/getUnreadRemind")
        fun getMessageRemind(@Body params: JsonObject?): Observable<BaseBean<RedPointBean>>
}

②然后可以使用JsonObject定义一个基础请求体,封装一些我们每次请求都会带的参数。

object BaseRequestParams {
    fun basePostParams(): JsonObject {
        val baseParams = JsonObject()
        baseParams.addProperty("device_id", DeviceUtil.getDeviceIMEI(getApplication()))
        baseParams.addProperty("platform", "android")
        return baseParams
    }
}

③最后进行请求

var mService = retrofit.create(IApi::class.java)
override fun getSearchRecommendWord(keyword: String): Observable<BaseBean<RecommendWordBean>> {
        val params = BaseRequestParams.basePostParams()
        params.addProperty("keyword", keyword)
        return mService.getMessageRemind(params)
}

总结

 Retrofit使用非常简单,首先转换接口,然后创建Retrofit实例,再实现接口,最后进行网络请求,回调处理数据。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容