文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

[Android]网络框架之OkHttp(详细)(kotlin)

2023-09-10 10:55

关注

目录

OkHttp的介绍

添加依赖

OkHttp的使用

get的同步与异步请求

post的同步与异步请求

POST请求的数据格式

POST请求上传文件

POST请求上传json对象

POST请求上传多个数据

OkHttp的配置

1.Builder构建器

2.自定义拦截器

3.自定义缓存

4. 自定义Cookie


OkHttp的介绍


https://square.github.io/okhttp/

由Square公司贡献的一个处理网络请求的开源项目,是目前Android使用最广泛的网络框架。从Android4.0开始HttpURLConnection的底层实现采用的是OkHttp

添加依赖


 implementation 'com.squareup.okhttp3:okhttp:4.9.0'

上述依赖会自动下载okhttp库和okio库 

OkHttp的使用

 记得添加权限!

get的同步与异步请求


get请求的基本步骤:

创建OkHttpClient的实例

创建Request对象,设置url地址

创建Call对象,调用它的execute方法(同步)或者enqueue方法(异步)来发送请求并获取服务器返回的数据

得到服务器返回的数据的具体内容

get同步请求 

//get同步请求    fun getSync() {        thread {            try {                val client = OkHttpClient()                val request = Request.Builder()                    .url("https://www.httpbin.org/get?a=1&b=2")                    .build()                val call=client.newCall(request)                val response = call.execute()//execute方法会阻塞在这里,必须等到服务器响应,得到response才会执行下面的代码                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("getSync", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

get异步请求 

//get异步请求    fun getAsync(){        val client = OkHttpClient()        val request = Request.Builder()            .url("https://www.httpbin.org/get?a=1&b=2")            .build()        val call=client.newCall(request)        //异步请求,enqueue方法不会阻塞后续代码的执行        call.enqueue(object :Callback{            //请求失败调用            override fun onFailure(call: Call, e: IOException) {            }            //请求结束调用(意味着与服务器的通信成功)            override fun onResponse(call: Call, response: Response) {                if(response.isSuccessful){                    response.body?.let { Log.e("getAsync", it.string()) }                }            }        })    }

 响应码在200到299之间就是成功的。

 

post的同步与异步请求


post请求的基本步骤:

创建OkHttpClient的实例

创建RequestBody对象来存放待提交的参数

创建Request对象,设置url地址,调用post方法,把RequestBody对象传入

创建Call对象,调用它的execute方法(同步)或者enqueue方法(异步)来发送请求并获取服务器返回的数据

得到服务器返回的数据的具体内容

post同步请求提交键值对

 //post同步请求    fun postSync(){        thread {            try {                val client = OkHttpClient()                val requestBody=FormBody.Builder().add("a","1").add("b","2").build()                val request = Request.Builder()                    .url("https://www.httpbin.org/post")                    .post(requestBody)                    .build()                val call=client.newCall(request)                val response = call.execute()//execute方法会阻塞在这里,必须等到服务器响应,得到response才会执行下面的代码                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("postSync", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

post异步请求提交键值对

//post异步请求    fun postAsync(){        val client = OkHttpClient()        val requestBody=FormBody.Builder().add("a","1").add("b","2").build()        val request = Request.Builder()            .url("https://www.httpbin.org/post")            .post(requestBody)            .build()        val call=client.newCall(request)        //异步请求,enqueue方法不会阻塞后续代码的执行        call.enqueue(object :Callback{            //请求失败调用            override fun onFailure(call: Call, e: IOException) {            }            //请求结束调用(意味着与服务器的通信成功,)            override fun onResponse(call: Call, response: Response) {                if(response.isSuccessful){                    response.body?.let { Log.e("postAsync", it.string()) }                }            }        })    }

POST请求的数据格式


协议规定POST提交的数据必须放在请求体中,但协议并没有规定数据必须使用什么编码方式。而常用的数据编码方式有:

注意:

 String、ByteArray、ByteString转RequestBody都用toRequestBody()

而File转RequestBody用asRequestBody()

POST请求上传文件


fun Filetest(){        thread {            try {                val client = OkHttpClient()                //创建文件                val file1=File(externalCacheDir,"jfApp")                if (!file1.exists()){                    file1.createNewFile();                }                //在file1中写入aaa                file1.printWriter().use { out->                    out.println("aaa")                }                //把file转化为RequestBody                val fileBody1=file1.asRequestBody("text/plain".toMediaType())                val request = Request.Builder()                    .url("https://www.httpbin.org/post")                    .post(fileBody1)                    .build()                val call=client.newCall(request)                val response = call.execute()                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("file", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

POST请求上传json对象


fun jsontest(){        thread {            try {                val client = OkHttpClient()                val json:String="{\"a\":1,\"b\":2}"                val requestBody=json.toRequestBody("application/json".toMediaType())                val request = Request.Builder()                    .url("https://www.httpbin.org/post")                    .post(requestBody)                    .build()                val call=client.newCall(request)                val response = call.execute()                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("jsontext", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

POST请求上传多个数据


fun Filetest(){        thread {            try {                val client = OkHttpClient()                //创建文件                val file1=File(externalCacheDir,"jfApp")                val file2=File(externalCacheDir,"jfApp2")                if (!file1.exists()){                    file1.createNewFile();                }                if (!file2.exists()){                    file2.createNewFile();                }                //在file1中写入aaa                file1.printWriter().use { out->                    out.println("aaa")                }                //把file转化为RequestBody                val fileBody1=file1.asRequestBody("text/plain".toMediaType())                val fileBody2=file2.asRequestBody("text/plain".toMediaType())                //把数据放入multipartBody中                val multipartBody = MultipartBody.Builder()                    .addFormDataPart("file1", file1.name,fileBody1)//添加文件                    .addFormDataPart("file2",file2.name,fileBody2)                     .addFormDataPart("a","1")//添加键值对                    .build()                val request = Request.Builder()                    .url("https://www.httpbin.org/post")                    .post(multipartBody)                    .build()                val call=client.newCall(request)                val response = call.execute()                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("file", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

OkHttp的配置

1.Builder构建器


val okHttpClient:OkHttpClient=OkHttpClient.Builder().build()

可以加入一些自己配置的小配件

2.自定义拦截器


okhttp的拦截器就是在intercept(chain: Interceptor.Chain)的回调中对Request和Response进行修改,然后通过chain.proceed(request)调起下一个拦截器。

val okHttpClient:OkHttpClient=OkHttpClient.Builder().addInterceptor(xxx).build()

val okHttpClient:OkHttpClient=OkHttpClient.Builder().addNetworkInterceptor(xxx).build()

addInterceptor()和addNetworkInterceptor()的区别:

addInterceptor()的优先级高于addNetworkInterceptor()。

在1的条件下,添加拦截器的的顺序就是执行的顺序。

在拦截器中修改Request添加请求头,就可以在每个Request对象中自动添加请求头,减少麻烦。

fun interceptor(){        thread {            try {                val okHttpClient:OkHttpClient=OkHttpClient.Builder()                    .addInterceptor(object : Interceptor{                        override fun intercept(chain: Interceptor.Chain): Response {//前置处理val request=chain.request().newBuilder()    .addHeader("os","android")    .addHeader("version","1.0").build()val response=chain.proceed(request)//后置处理return  response                        }                    })                    .build()                val request = Request.Builder()                    .url("https://www.httpbin.org/get?a=1&b=2")                    .build()                val call=okHttpClient.newCall(request)                val response = call.execute()//execute方法会阻塞在这里,必须等到服务器响应,得到response才会执行下面的代码                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("getSync", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }        }    }

3.自定义缓存


OkHttp按照Http协议规则实现了缓存的处理,缓存是比如:当我们发起第一次请求之后,如果后续还需要进行同样的请求,此时如果符合缓存规则,则可以减少与服务器的网络通信,直接从本地文件缓存中读取响应放回给请求者。但是在默认情况下,OkHttp的缓存是关闭状态,需要我们开启。

Cache(缓存文件地址,缓存最大容量字节)
 val okHttpClient:OkHttpClient=OkHttpClient.Builder()        .cache(Cache(File(externalCacheDir,"a"),1024*1024))         .build()                    

4. 自定义Cookie


 Cookie是某个网站为了辨别用户身份,进行会话跟踪(比如确定登录状态)而存储在用户本地终端上的数据(通常经过加密),由用户客户端计算机暂时或永久保存的信息。

我们在玩Android - wanandroid.com - 每日推荐优质文章

这个网站上注册账号,然后得到账号和密码。这个网站提供很多接口。

请求登录接口之后将返回cookie保存下来,才能请求其他接口,这里请求的是收藏列表。

fun cookietest(){         val cookies = HashMap>()          thread {              val okHttpClient:OkHttpClient=OkHttpClient.Builder().cookieJar(object :CookieJar{       //加载并保存cookie                  override fun loadForRequest(url: HttpUrl): List {                      val cookies: List? = cookies.get(url.host)                      if(cookies==null)                          return ArrayList()                      else {                          return cookies                      }                  }                  //保存cookie                  override fun saveFromResponse(url: HttpUrl, list: List) {                      cookies.put(url.host,list)                  }              }).build()              val fromBody=FormBody.Builder().add("username","xxx")                  .add("password","xxx").build()//网站的账号和密码              var request = Request.Builder()                  .url("https://www.wanandroid.com/user/login")                  .post(fromBody)                  .build()              var call=okHttpClient.newCall(request)            try {                val response = call.execute()                val requestData = response.body?.string()                if (requestData != null) {                    Log.e("cookietest", requestData)                }            } catch (e: Exception) {                e.printStackTrace()            }              request=Request.Builder().url("https://www.wanandroid.com/lg/collect/list/0/json")                  .build()              call=okHttpClient.newCall(request)              try {                  val Response=call.execute()                  Response.body?.let { Log.e("cookietest", it.string()) }              }catch (e:Exception){                  e.printStackTrace()              }        }    }

来源地址:https://blog.csdn.net/weixin_63357306/article/details/128918616

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯