数据存储 & 网络通信 | 青训营笔记

70 阅读3分钟

这是我参与「第四届青训营 」笔记创作活动的第7天

网络请求

简介

  • 客户端向服务端发起请求,服务端返回数据给到客户端
  • 由于网络请求在大型App里使用非常频繁,为了更好的支持业务迭代,一般会进行网络请求的封装

网络框架对比

img

说明:

  • Volley的Request和Response都是把数据方法放到byte[]数组里,不支持输入输出流,把数据放到数组中,如果大文件多了,数组就会非常大且多,消耗内存
  • 行业内,目前基本上都是Retrofit 和 OkHttp组合的这种方式来进行网络请求
  • IO 和 NIO这两个都是Java中的概念,如果我从硬盘读取数据,第一种方式就是程序一直等,数据读完后才能继续操作这种是最简单的也叫阻塞式IO,还有一种是你读你的,程序接着往下执行,等数据处理完你再来通知我,然后再处理回调。而第二种就是 NIO 的方式,非阻塞式, 所以NIO当然要比IO的性能要好了,而 Okio是 Square 公司基于IO和NIO基础上做的一个更简单、高效处理数据流的一个库。

总结:

  • 目前Retrofit和OkHttp的组合,功能更加全面,封装更加彻底,当下最为流行的网络请求方式,我们本文也会重点来关注Retrofit的使用和原理的介绍。

Retrofit的使用介绍

Retrofit其实是对OkHttp的一个封装,也是当前最为流行的一种网络请求组合方式。

使用举例

场景假设:客户端知道了一个用户的uid,想通过服务端查下这个用户的姓名,通过Retrofit如何实现呢? 接口:www.bytedance.com/users/{uid}… 其中{uid}要替换为实际的uid,例如1123,最终请求为www.bytedance.com/users/1123/…

类型:GET请求 接口返回:

 {
     "message": "success",
     "data": {
         "uid":"1123",
         "first_name":"张",
         "last_name":"三丰"
     }
 }

img

使用介绍

  • 添加Retrofit库的依赖

    • 在需要用到Retrofit接口的module中,新增依赖(最新的版本可看GitHub
 dependencies {
 implementation 'com.squareup.retrofit2:retrofit:2.4.0'
     //...其他依赖
 }
  • 创建 用于描述网络请求 的接口
 //接口类名:可自定义,尽量和这类请求的含义相关
 interface IUserInfoService {
 ​
     @GET("users/{uid}/name")
     fun getUserName(@Path("uid") uid: Int): Call<ResponseBody>
 ​
     //@GET("users/{name}/uid")
     //fun getRequest(@Path("name" name:String)) Call<User>
     
     //后续可以增加其他的接口,一个接口对应一个api请求
 }
 ​
 //函数名:可自定义,需要能识别出该接口的作用,该interface里可以增加多个不同的函数
 //@GET 注解:用于指定该接口的相对路径,并采用Get方法发起请求
 //@Path 注解:需要外部调用时,传入一个uid,该uid会替换@GET注解里相对路径的{uid}
 //返回值Call<ResponseBody>,这里用ResponseBody,我们可以直接拿到请求的String内容
 //如果要自动转为Model类,例如User,这里直接替换为User就好。
  • 发起网络请求
 fun getUserName(view: View) {
     //创建Retrofit实例
     val retrofit = Retrofit.Builder()
         .baseUrl("https://www.bytedance.com/")
         .build()
     //创建iUserInfoService实例
     val iUserInfoService = retrofit.create(IUserInfoService::class.java)
     //创建网络请求Call对象
     val call = iUserInfoService.getUserName(1123)
     //发起异步请求
     call.enqueue(object : Callback<ResponseBody> {
 ​
         override fun onResponse(call: Call<ResponseBody>,
                                 response: Response<ResponseBody>) {
             //请求成功时回调
             request_result_tv.text = "请求成功:" + response.body()!!.string()
         }
 ​
         override fun onFailure(call: Call<ResponseBody>, e: Throwable) {
             //请求失败时候的回调
             request_result_tv.text = "请求失败:" + e.message
         }
     })
 }

总结

  • 引入依赖库
  • 创建 用于描述网络请求 的接口
  • 发起网络请求

    • 创建Retrofit实例
    • 创建iUserInfoService实例
    • 创建网络请求Call对象
    • 使用Call对象发起异步请求