Android学习系列
Android之Room学习
Android之自定义View学习(一)
Android之自定义View学习(二)
Android之消息机制学习
Android学习之Navigation学习(一)Navigation初体验
Android学习之Retorfit2学习
Android学习之Retrofit2学习
前言
连更几天的数据结构与算法,有点肝不动了,虽然今天刚刚看了红黑树创建操作的具体情况,但是今天还是想给大家介绍一个比较火热的安卓网络请求库Retrofit2,主要还是说一下这一请求库的应用。
一、模拟请求网站
android有着诸多的网络请求架构与网络请求库,在介绍我们今天的主角Retrofit2之前,先介绍一个我们用于测试用的模拟请求网站:https://mock-api.com/app.html,它可以通过自定义GET/POST请求规则构建一个可以访问的url。
建立过程主要分为四个步骤:
- 创建自己的模拟系统,并进入模拟系统
-
创建中:
-
创建完成:
- 进入系统,定义所想要的请求规则(一般都是GET/POST)
左侧需要定义Request请求,右侧需要定义Response响应。当然注意格式一般都是json格式(Request部分也可以选择其他格式,但是表现在url上都大同小异)。
同时需要注意下大小写之分,因为这对我们后续Retrofit2的使用十分重要。
-
GET请求:
-
POST请求:
二、Retrofit2简介
Retrofit2是Square公司开源的网络请求封装库,其底层是基于OKHttp网络请求框架的实现的,当然OKHttp也是Square公司推出的罢了。搭配其他的框架(GSON格式的Response),Retrofit2使得请求变得简便,搭建变得更容易实现。
三、Retrofit2注解
下面列三个表格进行常用Retrofit2注解说明。一类是请求格式列表,一类是标记,还有一类是网络请求参数
请求格式列表:
注解请求形式 | 说明 |
---|---|
@GET | get请求 |
@POST | post请求 |
@HEAD | head请求 |
@PUT | put请求 |
@DELETE | delete请求 |
@PATCH | patch请求,对put请求进行 |
@OPTION | option请求 |
@HTTP | http/https请求,需要指明三个属性method,path,hasBody |
一般最常见的就是使用@GET和@POST注解。
而在GET请求,我们知晓,添加的参数(Query_String)均直接显示在url中。
标记
标记一般都是Post请求的其他几种数据传方式。
参数形式 | 说明 |
---|---|
@FormUrlEncoded | Post请求上传表单数据 |
@Multipart | Post请求上传文件数据 |
@Streaming | Post请求返回数据流形式数据,适用于大数据场景 |
网络请求参数列表:
-
@GET
| 网络请求参数形式 | 说明 |
| :-------: | :–: |
| @Query | 指定url后接单一参数 |
| @QueryMap | 指定url后接多个参数 | -
@POST
| 网络请求参数形式 | 说明 |
| :---------------: | :-----------------------------------------------------: |
| @Body | 用于post请求传输json格式数据 |
| @Field、@FieldMap | 与@FormUrlEncoded标记合用,用于post请求传输表单数据使用 |
| @Part、@PartMap | 与@Multipart标记合用,用于post传输文件使用 | -
通用
| 网络请求参数形式 | 说明 |
| :---------------: | :----------------------------------------: |
| @Header、@Headers | 添加请求头(header为添加不固定值的header) |
| @Path | 路径替换参数 |
| @URL | 设置URL |
四、Retrofit2使用
在分别给出上述网络请求方式的规则(GET and POST为例)之前,我们先来理清一下发起请求之前所需要做的准备工作。
Step 1 添加依赖库
//build.gradle.kt
dependencies {
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
testImplementation(kotlin("test-junit"))
}
这里添加了一个converter-gson用于将response的body进行数据格式转换。
Step 2 开始准备retrofit——定义接口,在其中声明请求函数以及返回 回调
interface WebService {
@GET("api/webInfo")
fun getWebInfo(): Call<WebInfo>
@GET("api/userInfo")
fun getUserInfo(@Query("id") id :Int): Call<UserInfo>
@GET("api/article/{bookName}/page/{page}")
fun getContentOfBook(@Path("bookName") bookName:String, @Path("page") page:Int) :Call<ResponseBody>
@POST("api/login")
fun login(@Body account : AccountInfo) : Call<UserInfo>
}
我们需要声明一个接口,此处为WebService,用于存储各种需要发送请求,对应于我们模拟网址的请求规则。
GET
@GET("api/userInfo")
fun getUserInfo(@Query("id") id :Int): Call<UserInfo>
@GET("api/article/{bookName}/page/{page}")
fun getContentOfBook(@Path("bookName") bookName:String, @Path("page") page:Int) :Call<ResponseBody>
从如上代码其实很好理解@Query和@Path
@Query:/api/userInfo?id=1
@Path:/api/article/zgmtqsx
/page/1
POST
@POST("api/login")
fun login(@Body account : AccountInfo) : Call<UserInfo>
post请求与上文所说Response字段需要与Call中返回类保持一致,post请求中Body->AsccountInfo也需要与Request请求的json字段保持一致。
Step 3 根据Response响应在定义的接口中定义返回的数据类型
如上面接口Call中的各种类,这些类中的变量定义与Response中的响应一致。
class AccountInfo {
private var user:String?=null
private var password:String?=null
constructor(user :String, password :String) {
this.user = user
this.password = password
}
}
class UserInfo {
private var userName :String?= null
private var id :Int?= null
private var account:String?=null
private var sex :String?= null
private var age :Int?= null
private var verifyCode :String?= null
fun getUserInfo(): String {
return "\t userName : $userName\n \t id : $id \n \t sex : $sex \n \t age : $age \n \t verifyCode : $verifyCode \n"
}
fun getLoginAccountInfo() :String {
return "\t userName : $userName\n \t id : $id \n \t account : $account \n \t verifyCode : $verifyCode \n"
}
}
正如博主所提醒,类的字段名需要与Response中的字段名保持一致,否则,会发现在Response之外的字段值在返回后为空。
Step 4 实例化Retrofit2,获取网络
val baseUrl = "http://mock-api.com/mnEPkRgJ.mock/"
val retrofit :Retrofit = Retrofit.Builder().
baseUrl(baseUrl).
addConverterFactory(GsonConverterFactory.create()).build()
val service :WebService = retrofit.create(WebService::class.java)
baseUrl代表着我们的请求前最基础的url,而后get/post请求均是在该url基础上加上参数或者是提交数据。
Step 5 开始网络请求(异步/同步)
Retrofit2 的底层网络请求还是OKHttp的,因此也沿用着同步execute和异步enqueue函数。
同步:execute()
var repsponse = service.getWebInfo().execute()
println(repsponse.body())
异步:enqueue()
service.getWebInfo().enqueue(object :Callback<WebInfo>{
override fun onResponse(call: Call<WebInfo>, response: Response<WebInfo>) {
if (response != null && response.body() != null) {
webInfo = response.body()
// println(response.body())
println(webInfo.toString())
}
}
override fun onFailure(call: Call<WebInfo>, t: Throwable) {
println(t.toString())
}
})
service.getUserInfo(id = 1).enqueue(object : Callback<UserInfo>{
override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
lin = response.body()
println(lin?.getUserInfo())
}
override fun onFailure(call: Call<UserInfo>, t: Throwable) {
println(t.toString())
}
})
service.getContentOfBook("zgmtqsx",1).enqueue(object :Callback<ResponseBody>{
override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
println(response)
}
override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
println(t.toString())
}
})
var accountInfo :AccountInfo= AccountInfo("44244242","12345")
service.login(accountInfo).enqueue(object :Callback<UserInfo>{
override fun onResponse(call: Call<UserInfo>, response: Response<UserInfo>) {
if (response.isSuccessful) {
lin = response.body()
println(lin?.getLoginAccountInfo())
}
}
override fun onFailure(call: Call<UserInfo>, t: Throwable) {
println(t.toString())
}
})
五、总结
以上就是博主目前所了解到REtrofit2的使用,当然文中并没有举例出全部的所有的例子,但是也是相对常见且相对够用的操作。希望对大家学习Retrofit2有所帮助。
其他学习分享系列
数据结构与算法系列
数据结构与算法之哈希表
数据结构与算法之跳跃表
数据结构与算法之字典树
数据结构与算法之2-3树
数据结构与算法之平衡二叉树
数据结构与算法之红黑树
数据结构与算法之十大经典排序
数据结构与算法之二分查找三模板
数据结构与算法之动态规划
数据结构与算法之回溯算法
数据结构与算法之Morris算法
数据结构与算法之贪心算法
数据结构与算法之摩尔投票
如有兴趣可以关注我的微信公众号,每周带你学一点算法与数据结构。