[Android]网络框架之Retrofit(kotlin)
创始人
2024-05-24 13:41:59
0

目录

 Retrofit简介

Retrofit基本使用

Retrofit的注解

Retrofit的转换器

文件的上传与下载 


 Retrofit简介


Retrofit是一款由Square公司开发的网络库,但是它和OkHttp的定位完全不同。

OkHttp侧重的是底层通信的实现,而Retrofit侧重的是上层接口的封装。

事实上,Retrofit就是Square公司在OkHttp的基础上进一步开发出来的应用层网络通信库,使得我们可以用更加面向对象的思维进行网络操作。

Retrofit的项目主页地址是:

https://github.com/square/retrofit

添加依赖

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

添加网络权限

 

Retrofit基本使用

1.根据Http接口创建kotlin接口

interface HttpbinService {@GET("get")fun get(@Query("userName")userName: String,@Query("password") pwd: String):Call@POST("post")@FormUrlEncodedfun post(@Field("userName")userName:String, @Field("password")pwd:String):Call
}

2.创建Retrofit对象,并生成接口实现类对象。

 val retrofit = Retrofit.Builder().baseUrl("https://www.httpbin.org/").build()val httpbinService: HttpbinService = retrofit.create(HttpbinService::class.java)

3.接口实现类对象调用对应方法获得响应。

val call: retrofit2.Call = httpbinService.post("xxx", "xxx")call.enqueue(object : retrofit2.Callback {//请求完成override fun onResponse(call: Call, response: Response) {try {Log.e("data", "${response.body()?.string()}")} catch (e: Exception) {e.printStackTrace()}}//请求失败override fun onFailure(call: Call, t: Throwable) {TODO("Not yet implemented")}})

Retrofit的注解


方法注解:@GET,@POST,@PUT,@DELECTE,@PATH,@HEAD,@OPTIONS,@HTTP

标记注解:@FormUrlEncoded,@Multiparty,@Streaming

参数注解:@Query,@QueryMap,@Body,@Field,@FieldMap,@Part,@PartMap

其他注解:@Path,@Header,@Headers,@Url

(1) @GET

https://www.httpbin.org/get

@GET("get")fun get():Call

这里使用了一个@GET注解,表示当调用get()方法时Retrofit会发起一条GET请求,请求的地址就是我们在@GET注解中传入的具体参数。另外,get()方法的返回值必须声明成Retrofit中内置的Call类型,并通过泛型来指定服务器响应的数据应该转换成什么对象。

(2) @GET, @Query

https://www.httpbin.org/get?userName=&password=

@GET("get")fun get(@Query("userName")userName: String,@Query("password") pwd: String):Call

 这里在get方法中添加了两个参数userName和pwd,并使用 @Query对他们进行声明,这样当发起网络请求时,Retrofit就会自动按照带参数GET请求的格式将这两个参数构建到请求地址中。

(3)@POST,@FormUrlEncoded,@Field

@POST("post")@FormUrlEncodedfun post(@Field("userName")userName:String, @Field("password")pwd:String):Call

这里使用了一个@POST注解,表示当调用post()方法时Retrofit会发起一条POST请求,请求的地址就是我们在@POST注解中传入的具体参数。POST请求如果参数,就需要添加 @FormUrlEncoded注解,表示请求实体是一个表单,每个键值对需要使用@Field注解。

@POST("post")@FormUrlEncodedfun post(@Field("userName")userName:String, @Field("password")pwd:String):Call

(4) @Path

@POST("{id}")@FormUrlEncodedfun postInPath(@Path("id")path:String,@Field("userName")userName:String, @Field("password")pwd:String):Call

 在POST注解指定的接口地址当中,这里使用了{id}的占位符,然后又在postInPath方法中添加了一个path参数,并使用@Path{”id“}注解来声明这个参数。这样当调用postInPath方法发起请求时,Retrofit会自动将id参数的值替换到占位符的位置,从而组成一个合法的请求地址。

(5)@HTTP

@HTTP(method = "GET", path = "get", hasBody = true)fun http(@Query("username")userName: String,@Query("password") pwd: String):Call

@HTTP注解,通过method设置请求方式(注意大小写),path设置网络请求地址,hasBody是否有请求体。

(6)@Body

@POST("post")fun postBody(@Body body:RequestBody):Call

POST请求并给它加入@Body注解,@Body可以传递自定义类型数据给服务器。如果我们声明参数的类型时会怎样呢?

@POST("post")fun postBody(@Body body:Data):Call

我们在postBody方法中声明Data类型的参数,这样当Retrofit发送POST请求的时候,就会自动将Data对象中的数据转换成JSON格式的文本,并放到HTTP请求的body部分,服务器在收到请求之后只需要将这部分解析出来。

(@Body注解不能与@FormUrlEncoded和@Multiparty一起用)

(7)@Header,@Headers

@Headers("os:android","version:1.0")@POST("post")fun postWithHeaders( @Header("a") a:String):Call

静态添加header声明,使用 @Headers

动态添加header声明,使用 @Header

(8)@Url

@POSTfun postUrl(@Url url:String):Call

@Url注解重写网络接口地址

Retrofit的转换器


在我们接到服务器的相应之后,目前无论是OkHttp还是Retrofit都只能接收到String字符串类型的数据,在实际开发中,我们经常需要对字符串进行解析将其转换为一个对象,比如服务器响应数据为JSON格式字符串,那么我们可以利用GSON库完成发序列化的操作。而Retrofit提供了多个转换器使得响应能够完成自动的数据转换,以JSON解析为例:

添加依赖

   implementation 'com.squareup.retrofit2:converter-gson:2.6.1'

由于retrofit会借助GSON将JSON数据转换成对象,需要新建一个类 

class App(val id:String,val name:String,val price:Double,val imagePath:String) {
}

 新建一个接口,获取JSON数据


interface AppService {@GET("get_JsonArray.json")fun getAppData(): Call>
}

由于这里服务器的接口是HTTP,从Android 9.0系统开始,应用程序默认允许使用HTTPS类型的网络请求,而我用的Apache服务器现在使用的是HTTP,所以要进行网络安全配置。

 新建network_config.xml文件



 最后,使用如下代码即可发起Retrofit请求:

val retrofit=Retrofit.Builder().baseUrl("http://10.0.2.2/").addConverterFactory(GsonConverterFactory.create()).build()val appService:AppService=retrofit.create(AppService::class.java)appService.getAppData().enqueue( object:retrofit2.Callback>{override fun onResponse(call: retrofit2.Call>,response: retrofit2.Response>) {val list=response.body()if(list!=null){for(a in list){Log.e("data","id=${a.id} name=${a.name} price=${a.price} imagePath=${a.imagePath}")}}}override fun onFailure(call: retrofit2.Call>, t: Throwable) {t.printStackTrace()}})

文件的上传与下载 


上传文件

fun uploadFileTest(){thread{try {val retrofit = Retrofit.Builder().baseUrl("https://www.httpbin.org/").build()val uploadService: UploadService = retrofit.create(UploadService::class.java)val file=File(externalCacheDir,"a.txt")if (!file.exists()){file.createNewFile();}val part:MultipartBody.Part=MultipartBody.Part.createFormData("file",file.name,file.asRequestBody("text/plain".toMediaType()))val call=uploadService.upload(part)Log.e("uploadFileTest","${call.execute().body()?.string()}")}catch (e:Exception){e.printStackTrace()}}}

下载文件 

//下载文件fun downloadTest(){thread {try {val retrofit = Retrofit.Builder().baseUrl("https://www.httpbin.org/").build()val uploadService: UploadService = retrofit.create(UploadService::class.java)val response=uploadService.downloaduri("https://dl2.xmind.cn/Xmind-for-Windows-x64bit-22.11.2677.exe").execute()val inputStream=response.body()?.byteStream()val file=openFileOutput("data111",Context.MODE_PRIVATE)val bis = BufferedInputStream(inputStream)val buffer = ByteArray(4096)var len: Intwhile (((bis.read(buffer)).also { len = it }) != -1) {file.write(buffer, 0, len)}bis.close()}catch (e:Exception){e.printStackTrace()}}}

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
在Word、WPS中插入AxM... 引言 我最近需要写一些文章,在排版时发现AxMath插入的公式竟然会导致行间距异常&#...
【PdgCntEditor】解... 一、问题背景 大部分的图书对应的PDF,目录中的页码并非PDF中直接索引的页码...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
修复 爱普生 EPSON L4... L4151 L4153 L4156 L4158 L4163 L4165 L4166 L4168 L4...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...