Android OkHttp 使用入门

AnRFDev 发表于 2021/10/27 17:38:26 2021/10/27
【摘要】 之前用HttpURLConnection GET和POST获取文本数据。现在来认识一下这款网络访问利器。OkHttp是一款HTTP客户端。有如下特点:连接池减少请求延迟(在HTTP/2不可用的情况下)传输GZIP时减少下载体积缓存相同请求的回复OkHttp能从连接故障中静默恢复。如果服务有多个IP地址,如果第一次访问失败,它会尝试其他地址。这功能对IPv4+IPv6和多个host的服务来说很...

之前用HttpURLConnection GET和POST获取文本数据。现在来认识一下这款网络访问利器。

OkHttp是一款HTTP客户端。有如下特点:

  • 连接池减少请求延迟(在HTTP/2不可用的情况下)
  • 传输GZIP时减少下载体积
  • 缓存相同请求的回复

OkHttp能从连接故障中静默恢复。如果服务有多个IP地址,如果第一次访问失败,它会尝试其他地址。
这功能对IPv4+IPv6和多个host的服务来说很有必要。

OkHttp支持现代TLS特性。

要求

目前OkHttp要求Android 5.0+ (API level 21+) ,或者Java 8+。

OkHttp依赖于Okio和Kotlin标准库。官方强烈建议我们保持OkHttp的更新。

OkHttp 3.12.x 支持Android 2.3+ (API level 9+) 和 Java 7+。

接下来介绍在Android开发中使用OkHttp。

Android引入依赖

先引入OkHttp依赖

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

以Gitee开放API为例 https://gitee.com/api/v5/swagger,拿这里的接口做示例。需要准备自己的gitee账号。

下面是GET和POST的实际操作,使用Kotlin开发。

GET

列出 star 了仓库的用户

这是个GET接口。url: https://gitee.com/api/v5/repos/rustfisher/AndroidTutorial/stargazers?page=1&per_page=20

用curl命令可以拿到获取结果

curl -X GET --header 'Content-Type: application/json;charset=UTF-8' 'https://gitee.com/api/v5/repos/rustfisher/AndroidTutorial/stargazers?page=1&per_page=20'

发起GET请求

private fun get1() {
    val client = OkHttpClient()
    val request = Request.Builder().url("https://gitee.com/api/v5/repos/rustfisher/AndroidTutorial/stargazers?page=1&per_page=20")
            .build()
    request.header("Content-Type: application/json;charset=UTF-8")
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            Log.d(TAG, "[get1] onFailure: $call\n$e")
        }

        override fun onResponse(call: Call, response: Response) {
            Log.d(TAG, "[get1] onResponse: $call\n$response")
            if (response.code == 200) {
                // 请求成功 response.body!!.string()
            }
        }
    })
}
  • 创建OkHttpClient客户端对象client
  • 然后创建Request请求对象request
  • request设置header,request.header("Content-Type: application/json;charset=UTF-8")
  • 把请求交给客户端加入请求队列
    • enqueue(object : Callback)方法可以传入一个Callback回调
  • 请求到的结果在response.body

POST

创建代码片段

gitee有代码片段(gist)功能,以创建代码片段这个接口为例。

接口文档: https://gitee.com/api/v5/swagger#/postV5Gists

下面是接口描述

Parameter Value Description Type Data Type
access_token(必传) (登录gitee获得) 用户授权码 formData string
files(必传) 代码片段文件名及内容。如: { “f1.txt”: { “content”: “内容” } } formData object
description(必传) 代码片段描述,1~30个字符 formData string
public 公开/私有,默认: 私有 formData boolean

相关代码

private fun post1() {
    val mediaType = "application/json; charset=utf-8".toMediaType()
    val client = OkHttpClient()
    val postData = buildJson1()
    val body = buildJson1().toString().toRequestBody(mediaType)
    Log.d(TAG, "post1: $postData")
    val request = Request.Builder().url("https://gitee.com/api/v5/gists")
            .post(body)
            .build()
    val resp = client.newCall(request).execute() // 立刻执行 会阻塞当前线程
    if (resp.code >= 200 || resp.code <= 201) {
        val resStr = resp.body!!.string()
        Log.d(TAG, "post1: resp body: $resStr")
        mHandler.post { binding.resTv.text = resStr }
    }
}

private fun buildJson1(): JSONObject {
    val map = HashMap<String, Any>()
    map["access_token"] = "0d6f65ef07976154138e126764303622"
    val file1Map = HashMap<String, Any>()
    file1Map["content"] = "# POST测试 \n rustfisher.com"
    val file2Map = HashMap<String, Any>()
    file2Map["content"] = "# 第二个文件 \n an.rustfisher.com"
    val filesMap = HashMap<String, Any>()
    filesMap["file1"] = file1Map
    filesMap["file2"] = file2Map
    map["files"] = filesMap
    map["description"] = "测试POST接口"
    return JSONObject(map as Map<*, *>)
}

这里需要上报一些信息,用JSONObject装载信息。得到的json内容,再转成RequestBody。

最后交给OkHttp客户端去执行请求。注意这里要在子线程中操作。

小结

上面我们演示了OkHttp的基本用法。

以上2个例子我们可以看出enqueueexecute的不同。
enqueue是异步方法,会把网络访问放到子线程去。
execute会在当前线程执行请求。

使用的时候需要注意区分,避免在主线程里进行了网络访问。

如果需要顺序发起多个网络请求,可以考虑在一个子线程里用execute来进行访问。

在实际工程中,我们也经常采用OkHttp + Retrofit的方式。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区),文章链接,文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件至:cloudbbs@huaweicloud.com进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容。
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。