上一篇
安卓如果获取服务器数据
- 行业动态
- 2025-04-24
- 3473
安卓通过Retrofit/OkHttp发起HTTP请求,解析JSON数据,在子线程处理后更新
网络权限配置
在AndroidManifest.xml中声明网络权限:
<uses-permission android:name="android.permission.INTERNET" />
主流网络请求方式对比
工具 | 特点 | 适用场景 |
---|---|---|
HttpURLConnection | 原生API,需手动处理连接/线程/数据解析 | 简单请求,学习底层原理 |
OkHttp | 高效连接池,支持拦截器 | 中等复杂度项目 |
Retrofit | 基于OkHttp,通过注解生成接口,支持多种数据格式 | 复杂API调用,快速开发 |
Volley | 轻量级,内置缓存机制 | 简单GET/POST,图片加载 |
Retrofit实现步骤(以Kotlin为例)
添加依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
定义数据模型
data class User(val id: Int, val name: String, val email: String)
创建API接口
interface ApiService { @GET("users/{id}") suspend fun getUser(@Path("id") userId: Int): Response<User> }
配置Retrofit实例
val retrofit = Retrofit.Builder() .baseUrl("https://jsonplaceholder.typicode.com/") .addConverterFactory(GsonConverterFactory.create()) .build()
val apiService = retrofit.create(ApiService::class.java)
5. 异步调用(协程版)
```kotlin
GlobalScope.launch(Dispatchers.IO) {
try {
val response = apiService.getUser(1)
if (response.isSuccessful) {
val user = response.body()!!
// 更新UI需切换到主线程
withContext(Dispatchers.Main) {
// 显示user数据
}
} else {
// 处理错误码
}
} catch (e: Exception) {
// 网络异常处理
}
}
关键注意事项
主线程限制:Android禁止在主线程执行网络操作,需使用:
AsyncTask
(已过时)Coroutine
(推荐)RxJava
HandlerThread
HTTPS安全:
- 部署SSL证书(推荐)
- 测试环境可临时禁用证书验证(不推荐):
val sslSocketFactory = SSLContext.getDefault().socketFactory val trustManager = object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>, authType: String) {} override fun checkServerTrusted(chain: Array<out X509Certificate>, authType: String) {} override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf() } val client = OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManager) .hostnameVerifier { _, _ -> true } .build()
数据解析:
- JSON:
Gson
/Moshi
/Jackson
- XML:
Simple
/SAX
解析器 - Protobuf:高性能二进制序列化
- JSON:
完整示例代码
// 1. 配置Retrofit val retrofit = Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .client(OkHttpClient.Builder().apply { connectTimeout(10, TimeUnit.SECONDS) readTimeout(10, TimeUnit.SECONDS) }.build()) .build() // 2. 定义API接口 interface ApiService { @GET("data") suspend fun fetchData(@Query("page") page: Int): Response<DataModel> } // 3. 发起请求 lifecycleScope.launchWhenStarted { val api = retrofit.create(ApiService::class.java) try { val response = api.fetchData(1) if (response.isSuccessful) { // 处理数据 } else { // 处理HTTP错误码 } } catch (e: IOException) { // 处理网络异常 } }
相关问题与解答
Q1:如何处理网络请求中的超时和重试?
A:
- 设置超时:在OkHttpClient中配置
connectTimeout
/readTimeout
/writeTimeout
- 自动重试:
- 使用
interceptor
实现指数退避重试val retryInterceptor = Interceptor { chain -> var result = chain.proceed(chain.request) var retryCount = 0 while (!result.isSuccessful && retryCount < 3) { retryCount++ result = chain.proceed(chain.request) } result }
- 使用
Retrofit
的Call
适配器配合RxJava
/Coroutine
实现重试逻辑
- 使用
Q2:如何将服务器返回的JSON数组转换为对象列表?
A:
- 定义数据类:确保字段名与JSON键匹配
data class Item(val id: Int, val name: String)
- 使用转换器:
- Gson自动将
JsonArray
转换为List<Item>
@GET("items") suspend fun getItems(): Response<List<Item>>
- 或手动解析:
val type = object : TypeToken<List<Item>>() {}.type val items: List<Item> = Gson().fromJson(jsonArray, type)
- Gson自动将