Android学习之Retrofit2学习

Android

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。
建立过程主要分为四个步骤:

  1. 创建自己的模拟系统,并进入模拟系统
  • 创建中:
    新建模拟系统

  • 创建完成:
    模拟系统给

  1. 进入系统,定义所想要的请求规则(一般都是GET/POST)
    左侧需要定义Request请求,右侧需要定义Response响应。当然注意格式一般都是json格式(Request部分也可以选择其他格式,但是表现在url上都大同小异)。
    Request请求格式
    同时需要注意下大小写之分,因为这对我们后续Retrofit2的使用十分重要。
  • GET请求:
    GET

  • POST请求:
    POST

二、Retrofit2简介

Retrofit2是Square公司开源的网络请求封装库,其底层是基于OKHttp网络请求框架的实现的,当然OKHttp也是Square公司推出的罢了。搭配其他的框架(GSON格式的Response),Retrofit2使得请求变得简便,搭建变得更容易实现。

三、Retrofit2注解

下面列三个表格进行常用Retrofit2注解说明。一类是请求格式列表,一类是标记,还有一类是网络请求参数

请求格式列表:

注解请求形式说明
@GETget请求
@POSTpost请求
@HEADhead请求
@PUTput请求
@DELETEdelete请求
@PATCHpatch请求,对put请求进行
@OPTIONoption请求
@HTTPhttp/https请求,需要指明三个属性method,path,hasBody

一般最常见的就是使用@GET和@POST注解。
而在GET请求,我们知晓,添加的参数(Query_String)均直接显示在url中。

标记

标记一般都是Post请求的其他几种数据传方式。

参数形式说明
@FormUrlEncodedPost请求上传表单数据
@MultipartPost请求上传文件数据
@StreamingPost请求返回数据流形式数据,适用于大数据场景

网络请求参数列表:

  1. @GET
    | 网络请求参数形式 | 说明 |
    | :-------: | :–: |
    | @Query | 指定url后接单一参数 |
    | @QueryMap | 指定url后接多个参数 |

  2. @POST
    | 网络请求参数形式 | 说明 |
    | :---------------: | :-----------------------------------------------------: |
    | @Body | 用于post请求传输json格式数据 |
    | @Field、@FieldMap | 与@FormUrlEncoded标记合用,用于post请求传输表单数据使用 |
    | @Part、@PartMap | 与@Multipart标记合用,用于post传输文件使用 |

  3. 通用
    | 网络请求参数形式 | 说明 |
    | :---------------: | :----------------------------------------: |
    | @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

ET书籍

    @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算法

数据结构与算法之贪心算法

数据结构与算法之摩尔投票

如有兴趣可以关注我的微信公众号,每周带你学一点算法与数据结构。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IT 涓涓清泉

感谢打赏,我会更加努力写更好的

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值