[Android]网络框架之Retrofit(kotlin)

news2025/6/8 6:49:58

目录

 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'

添加网络权限

 <uses-permission android:name="android.permission.INTERNET" />

Retrofit基本使用

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

interface HttpbinService {
    @GET("get")
    fun get(@Query("userName")userName: String,@Query("password") pwd: String):Call<ResponseBody>

    @POST("post")
    @FormUrlEncoded
    fun post(@Field("userName")userName:String, @Field("password")pwd:String):Call<ResponseBody>
}

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<ResponseBody> = httpbinService.post("xxx", "xxx")
        call.enqueue(object : retrofit2.Callback<ResponseBody> {
            //请求完成
            override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                try {
                    Log.e("data", "${response.body()?.string()}")
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }

            //请求失败
            override fun onFailure(call: Call<ResponseBody>, 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<ResponseBody>

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

(2) @GET, @Query

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

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

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

(3)@POST,@FormUrlEncoded,@Field

@POST("post")
    @FormUrlEncoded
    fun post(@Field("userName")userName:String, @Field("password")pwd:String):Call<ResponseBody>

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

@POST("post")
    @FormUrlEncoded
    fun post(@Field("userName")userName:String, @Field("password")pwd:String):Call<ResponseBody>

(4) @Path

@POST("{id}")
    @FormUrlEncoded
    fun postInPath(@Path("id")path:String,@Field("userName")userName:String, @Field("password")pwd:String):Call<ResponseBody>

 在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<ResponseBody>

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

(6)@Body

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

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

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

我们在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<ResponseBody>

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

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

(8)@Url

@POST
    fun postUrl(@Url url:String):Call<ResponseBody>

@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<List<App>>
}

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

<application
    android:allowBackup="true"
    android:dataExtractionRules="@xml/data_extraction_rules"
    android:fullBackupContent="@xml/backup_rules"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.OkhttpRetrofit"
    tools:targetApi="31"
    android:networkSecurityConfig="@xml/network_config">

 新建network_config.xml文件

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

 最后,使用如下代码即可发起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<List<App>>{
            override fun onResponse(
                call: retrofit2.Call<List<App>>,
                response: retrofit2.Response<List<App>>
            ) {
               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<List<App>>, 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: Int
               while (((bis.read(buffer)).also { len = it }) != -1) {
                   file.write(buffer, 0, len)
               }
               bis.close()
           }catch (e:Exception){
               e.printStackTrace()
           }
       }

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/334543.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

永磁同步电机中BEMF电阻的作用

一、电路原理图 二、原理分析 如图一我们测的是相电压&#xff0c;从理论上我们知道我们测得相电压是一个马鞍波形&#xff0c;马鞍波形中并没有隐含 转子的位置和速度信息。那么为什么我们还要有这样一个电路呢&#xff1f; 这个问题其实困惑了我好久&#xff1f;直到有一天…

曹云金对德云社最大的贡献,就是促进了薪酬体系改革

虽然曹云金已经离开德云社&#xff0c;但是关于他和德云社的话题&#xff0c;却从来没有间断过&#xff0c;尤其是他和小岳岳的对比&#xff0c;更是很有争议的一个话题。实话实说&#xff0c;曹云金在德云社的这些年&#xff0c;对这个这个民间相声社团发展&#xff0c;还是做…

Docker实战

目录一、FROM 语法二、label语法三、run语法四、workdir 语法五、add 和copy 语法六、ENV语法七、volume 和expose 语法八、run、cmd 和entrypoint一、FROM 语法scratch -- 从头开始尽量来使用官方提供的imageFROM 指定基础镜像&#xff0c;最好挑一些apline&#xff0c;slim之…

Qml学习——控件状态

最近在学习Qml&#xff0c;但对Qml的各种用法都不太熟悉&#xff0c;总是会搞忘&#xff0c;所以写几篇文章对学习过程中的遇到的东西做一个记录。 学习参考视频&#xff1a;https://www.bilibili.com/video/BV1Ay4y1W7xd?p1&vd_source0b527ff208c63f0b1150450fd7023fd8 其…

Apache安全加固配置教程(小白篇)

Apache安全加固配置教程(小白篇) 资源宝分享&#xff1a;www.httple.net 一&#xff0c;Apache服务器的介绍 Apache服务器它是Internet网上应用最为广泛的Web服务器软件之一。Apache服务器源自美国国家超级技术计算应用中心&#xff08;NCSA&#xff09;的 Web服务器项目中。目…

SAS应用入门学习笔记3

操作数据集的观测&#xff1a; Eg. 修改变量值等 变量的值取出来&#xff0c;那么我们需要对变量的值进行修改 weight height bmi? Missing 用到条件语if then、赋值语句、表达式 等。 表达式是操作数和操作符的序列。 例如&#xff1a;3 x x1 1、操作数&#xff1a;…

每日学术速递2.9

CV - 计算机视觉 | ML - 机器学习 | RL - 强化学习 | NLP 自然语言处理 Subjects: cs.CV、cs.AI、cs.LG、cs.IR 1.Graph Signal Sampling for Inductive One-Bit Matrix Completion: a Closed-form Solution(ICLR 2023) 标题&#xff1a;归纳单比特矩阵完成的图信号采样&am…

程序员该不该在年后跳槽?3个问句给你答案

过完春节&#xff0c;2023年也迎来了第二个月份&#xff0c;有些程序员虽然还在公司上班&#xff0c;但是私底下跳槽的心蠢蠢欲动&#xff0c;简历说不定都改到第三版了。 在各大社交平台上&#xff0c;经常能看到不少程序员分享自己的跳槽经历&#xff0c;尤其是春节后更是如…

13薪|运营策划[北京市 - 海淀区]-10k-15k

"众推职聘”以交付结果为宗旨的全流程化招聘服务平台&#xff01;今日招聘信息↓【工作内容】1、根据项目要求&#xff0c;收集相关数据&#xff0c;策划撰写项目运营方案&#xff1b;2、运营合作环节中&#xff0c;监督管理执行&#xff1b;3、参与项目的评估&#xff1b…

WorkTool无障碍服务实现企业微信机器人接口

前言 想要实现一个企业微信机器人&#xff0c;如京东/拼多多福利群、美团瑞幸定时营销群、自助订单查询、智能咨询或社群管理机器人等&#xff0c;首先官方未提供外部群/客户群的机器人API&#xff0c;会话存档也只在一定场景下适用&#xff0c;及时使用会话存档也存在只能收不…

56 门控循环单元(GRU)【动手学深度学习v2】

56 门控循环单元&#xff08;GRU&#xff09;【动手学深度学习v2】 深度学习学习笔记 学习视频&#xff1a;https://www.bilibili.com/video/BV1mf4y157N2/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 门控循环单元GRU GRU和LSTM 实际上效果差不多。…

030_SSS_MaskSketch Unpaired Structure-guided Masked Image Generation

MaskSketch: Unpaired Structure-guided Masked Image Generation 1. Introduction 本文在MaskGIT的基础上进行了改进&#xff0c;提出了MaskSketch用于sketch-to-photo。MaskSketch直接使用预训练好的MaskGIT&#xff0c;不需要进行模型的训练&#xff0c;而且不需要成对的监…

29 - 面向对象的三大特征 - 多态

目录 一、理解多态 1、概念 2、使用场景 3、特点 二、多态案例1 1、需求 2、代码实现 一、理解多态 1、概念 不同的子类对象调用相同的父类方法&#xff0c;产生不同的执行结果2、使用场景 以继承和重写父类方法为前提是调用方法的技巧&#xff0c;不会影响到类的内部设计3、特…

Kubernetes那点事儿——健康检查

K8s应用程序生命周期管理——健康检查前言一、重启策略二、健康检查三、健康监控方式前言 官网&#xff1a;https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes 一、重启策略 Always&a…

云原生技术在容器方面的应用

随着近几年云原生生态的不断壮大&#xff0c;众多企业纷纷开展了用云上云的工作&#xff0c;学习和了解云原生及容器技术对于现代工程师是必不可少的&#xff0c;本文主要为大家介绍云原生及其在容器方面的应用。 1.1 什么是云原生 云原生技术有利于各组织在公有云、私有云和…

基于可视化 BI 工具 DataEase 制作第七次人口普查数据分析大屏

一、制作第七次人口普查数据大屏的背景介绍&#xff1a;第七次人口普查刚刚结束&#xff0c;想要制作一个大屏&#xff0c;能够直观的看到人口总数、出生人数、死亡人数等的情况&#xff1b;希望能够直观的看到人口分布的情况、各种比例、年龄结构等有一定的了解&#xff1b;直…

【网络原理篇2】TCP报头详解

在这一篇文章当中&#xff0c;了解到TCP是属于传输层的协议&#xff1b;当数据从应用层向传输层发送的时候&#xff0c;如果使用的是TCP协议&#xff0c;那么就需要把应用层的数据加上TCP报头。初识网络&#xff1a;IP、端口、网络协议、TCP-IP五层模型_革凡成圣211的博客-CSDN…

2023年去培训机构学前端还是Java?

选择专业肯定是优先考虑更有发展前景和钱途的专业。毕竟IT专业的培训费都不低&#xff0c;基本都要一两万左右&#xff0c;咱们花钱总是希望获得最大回报。 那么到底哪个更有发展前景呢&#xff1f; 零基础能学得会吗&#xff1f; 就业薪资如何呢&#xff1f; 前言 不知道大家有…

Python运算符优先级

以下表格列出了从最高到最低优先级的所有运算符&#xff1a;运算符描述**指数 (最高优先级)~ -按位翻转, 一元加号和减号 (最后两个的方法名为 和 -)* / % //乘&#xff0c;除&#xff0c;取模和取整除 -加法减法>> <<右移&#xff0c;左移运算符&位 AND^ |位…

pyqt5:python读取二进制文件(音频PCM文件)显示波形

文章目录1.使用ffmpeg生成PCM文件1.1 用 ffprobe 查看文件信息1.2 用 ffmpeg 命令转换1.3 用ffplay 测试播放PCM文件2.python读取PCM文件显示波形2.1 函数numpy.fromfile2.2 数据类型dtype说明3.源码和PCM文件链接有个项目需要输出10-50Hz的低频信号驱动线圈&#xff0c;考虑使…