前言
目前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
}
③生成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 {
override fun onFailure(call: Call, t: Throwable) {
Log.d(tag,"onFailure")
}
override fun onResponse(call: Call, response: Response) {
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
interface WordService {
@GET("/xhzd/query")
fun getWord(@Query("word") word: String, @Query("dtype") dtype: String,@Query("key") key: String): Observable
}
②调用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>
}
②然后可以使用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> {
val params = BaseRequestParams.basePostParams()
params.addProperty("keyword", keyword)
return mService.getMessageRemind(params)
}
总结
Retrofit使用非常简单,首先转换接口,然后创建Retrofit实例,再实现接口,最后进行网络请求,回调处理数据。