Android OkHttp用法详解

710 阅读2分钟

OkHttp 是一个高效、灵活的 HTTP 客户端库,在 Android 开发中非常常用。下面介绍如何在 Android 中使用 OkHttp,并附上常见的 GET 和 POST 请求示例。

1. 添加 OkHttp 依赖

如果你还没有添加 OkHttp,需要在 build.gradle.kts 添加依赖:

dependencies {
    implementation("com.squareup.okhttp3:okhttp:4.12.0") // 最新版
}

如果你用的是 build.gradle(Groovy 语法):

dependencies {
    implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}

2. 基本的 GET 请求(同步)

import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
​
fun sendGetRequest(): String? {
    val client = OkHttpClient() // 创建 OkHttpClient 实例
​
    val request = Request.Builder()
        .url("https://api.example.com/data") // 目标 URL
        .get() // GET 请求
        .build()
​
    return try {
        val response: Response = client.newCall(request).execute() // 执行请求(同步)
        if (response.isSuccessful) response.body?.string() else null
    } catch (e: IOException) {
        e.printStackTrace()
        null
    }
}

说明

  • OkHttpClient:创建 HTTP 客户端实例。
  • Request.Builder():构建 HTTP 请求。
  • .execute():执行 同步请求(会阻塞线程)。
  • response.body?.string():获取服务器返回的字符串。

3. GET 请求(异步)

如果你不想阻塞主线程,可以使用 异步请求

import okhttp3.*
import java.io.IOException
//callback 变量最终是用来将结果传递到最下面的回调函数里的,这个 回调函数 里的 result 就是 callback 传递的值
fun sendGetRequestAsync(callback: (String?) -> Unit) {
    val client = OkHttpClient()
    val request = Request.Builder().url("https://api.example.com/data").build()
​
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            callback(null) // 发生错误,返回 null到下面回调函数的result中
        }
        override fun onResponse(call: Call, response: Response) {
            callback(response.body?.string()) // 请求成功,把返回的数据传递给回调函数中的result
        }
    })
}
​
// 调用示例
fun main() {
    sendGetRequestAsync { result ->
        if (result != null) {
            println("服务器返回数据:$result")
        } else {
            println("请求失败")
        }
    }
}
​

说明

  • .enqueue():使用异步请求,不会阻塞主线程。
  • onFailure:请求失败时回调。
  • onResponse:请求成功时回调,并返回数据。

4. POST 请求(JSON 数据)

import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody
import okhttp3.Response
​
fun sendPostRequest(json: String): String? {
    val client = OkHttpClient()
​
    val requestBody = RequestBody.create("application/json".toMediaTypeOrNull(), json)//这里的json是传入的参数
​
    val request = Request.Builder()
        .url("https://api.example.com/login")
        .post(requestBody)
        .build()
​
    return try {
        val response: Response = client.newCall(request).execute()
        if (response.isSuccessful) response.body?.string() else null
    } catch (e: IOException) {
        e.printStackTrace()
        null
    }
}

使用

val jsonData = """{"username":"test","password":"123456"}"""
val response = sendPostRequest(jsonData)
println("服务器返回: $response")

异步版本POST请求

import okhttp3.*
import java.io.IOException
​
fun sendPostRequestAsync(json: String, callback: (String?) -> Unit) {
    val client = OkHttpClient()
​
    // 创建请求体
    val requestBody = RequestBody.create("application/json".toMediaTypeOrNull(), json)
​
    // 创建请求
    val request = Request.Builder()
        .url("https://api.example.com/login")
        .post(requestBody)
        .build()
​
    // 异步请求,使用 enqueue 发送请求
    client.newCall(request).enqueue(object : Callback {
        override fun onFailure(call: Call, e: IOException) {
            callback(null)  // 请求失败,传递 null 给回调
        }
​
        override fun onResponse(call: Call, response: Response) {
            // 请求成功时,检查响应状态
            if (response.isSuccessful) {
                callback(response.body?.string())  // 请求成功,传递响应内容给回调
            } else {
                callback(null)  // 如果请求不成功,传递 null
            }
        }
    })
}
​
​
//如何使用如下所示
fun main() {
    val json = """{"username":"test", "password":"123456"}"""
​
    sendPostRequestAsync(json) { result ->
        if (result != null) {
            println("请求成功,返回数据:$result")
        } else {
            println("请求失败")
        }
    }
}
​
​

5. 在 Android 里使用(结合协程)

在 Android 开发中,推荐 协程+OkHttp,避免阻塞 UI 线程:

suspend fun fetchData(): String? {
    return withContext(Dispatchers.IO) {
        val client = OkHttpClient()
        val request = Request.Builder()
            .url("https://api.example.com/data")
            .get()
            .build()
​
        try {
            val response = client.newCall(request).execute()
            if (response.isSuccessful) response.body?.string() else null
        } catch (e: IOException) {
            e.printStackTrace()
            null
        }
    }
}

Activity 中调用

lifecycleScope.launch {
    val data = fetchData()
    textView.text = data // 更新 UI
}

总结

请求方式方法是否阻塞线程
GETexecute()同步(会阻塞)
GET(异步)enqueue()异步(不会阻塞)
POSTexecute()同步(会阻塞)
POST(协程)withContext(Dispatchers.IO)推荐(不会阻塞)
  • 在 Android 里,推荐使用

    • enqueue() (异步回调)
    • withContext(Dispatchers.IO) (协程)
  • 避免在主线程执行 execute(),否则会导致 ANR(应用无响应)