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
}
总结
| 请求方式 | 方法 | 是否阻塞线程 |
|---|---|---|
| GET | execute() | ✅ 同步(会阻塞) |
| GET(异步) | enqueue() | ❌ 异步(不会阻塞) |
| POST | execute() | ✅ 同步(会阻塞) |
| POST(协程) | withContext(Dispatchers.IO) | ✅ 推荐(不会阻塞) |
-
在 Android 里,推荐使用:
enqueue()(异步回调)withContext(Dispatchers.IO)(协程)
-
避免在主线程执行
execute(),否则会导致 ANR(应用无响应) 。