上一篇
安卓如何接收服务器返回的数据
- 行业动态
- 2025-04-23
- 4599
通过HttpURLConnection或OkHttp发起请求,在输入流中读取服务器响应数据,解析为JSON/XML等格式,注意在子线程处理网络
网络请求基础
在安卓中接收服务器数据通常基于HTTP协议,需通过HttpURLConnection
或第三方库(如OkHttp、Retrofit)发起请求并处理响应。
添加网络权限
在AndroidManifest.xml
中声明网络权限:
<uses-permission android:name="android.permission.INTERNET" />
同步与异步请求
- 同步请求:直接调用网络API,会阻塞主线程(不推荐)。
- 异步请求:通过子线程或框架回调处理,避免UI卡顿。
使用OkHttp接收数据
OkHttp是安卓主流的网络请求库,支持同步/异步请求。
依赖配置
在build.gradle
中添加依赖:
implementation 'com.squareup.okhttp3:okhttp:4.10.0'
异步请求示例
OkHttpClient client = new OkHttpClient(); Request request = new Request.Builder() .url("https://api.example.com/data") .build(); client.newCall(request).enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) { // 处理失败(如网络错误) } @Override public void onResponse(Call call, Response response) throws IOException { if (response.isSuccessful()) { String responseBody = response.body().string(); // 解析数据(如JSON) } else { // 处理HTTP错误码 } } });
使用Retrofit接收数据
Retrofit基于OkHttp,提供更简洁的接口定义和数据解析。
依赖配置
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // 支持JSON解析
定义接口与回调
// 定义API接口 public interface ApiService { @GET("data") Call<MyDataClass> getData(); // MyDataClass需与JSON结构匹配 } // 创建Retrofit实例 Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); ApiService apiService = retrofit.create(ApiService.class); // 异步请求 apiService.getData().enqueue(new Callback<MyDataClass>() { @Override public void onResponse(Call<MyDataClass> call, Response<MyDataClass> response) { if (response.isSuccessful()) { MyDataClass data = response.body(); // 使用数据 } else { // 处理错误 } } @Override public void onFailure(Call<MyDataClass> call, Throwable t) { // 处理失败 } });
数据解析方式
根据服务器返回的数据格式选择解析方式:
数据格式 | 解析工具 | 示例 |
---|---|---|
JSON | Gson、Moshi、FastJSON | Gson gson = new Gson();<br>MyDataClass data = gson.fromJson(jsonString, MyDataClass.class); |
XML | SAX、DOM、Pull解析器 | 使用XmlPullParser 逐行解析 |
Protobuf | Google Protocol Buffer | 高效二进制解析 |
异步处理与线程管理
为避免阻塞UI线程,需在子线程处理网络请求,并通过Handler或LiveData更新UI。
使用Kotlin协程(推荐)
viewModelScope.launch { try { val response = apiService.getData() if (response.isSuccessful) { _data.postValue(response.body()) // LiveData更新UI } else { // 处理错误 } } catch (e: Exception) { // 处理异常 } }
传统AsyncTask(已过时)
new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... voids) { // 执行网络请求并返回结果 } @Override protected void onPostExecute(String result) { // 更新UI } }.execute();
常见问题与解决方案
问题 | 原因 | 解决方案 |
---|---|---|
网络请求失败 | 无网络、URL错误、服务器宕机 | 检查网络连接,确认URL,处理HTTP错误码 |
主线程阻塞 | 在UI线程执行网络操作 | 使用异步请求或协程 |
JSON解析失败 | 数据格式不匹配 | 检查字段名与类型,使用@SerializedName 注解映射 |
内存泄漏 | 未正确关闭输入流 | 在finally 块中关闭response.body() |
相关问题与解答
问题1:如何解析复杂的JSON嵌套结构?
解答:使用Gson的@SerializedName
注解映射嵌套字段,或定义嵌套类。
public class ResponseData { @SerializedName("user") private User user; // Getter/Setter } public class User { @SerializedName("name") private String name; // Getter/Setter }
问题2:如何处理网络请求的超时和重试?
解答:
- 设置超时:在OkHttpClient中配置超时时间:
OkHttpClient client = new OkHttpClient.Builder() .connectTimeout(10, TimeUnit.SECONDS) .readTimeout(10, TimeUnit.SECONDS) .build();
- 重试机制:使用拦截器或第三方库(如
Retrofit2-Retry
):// 自定义重试逻辑(简化示例) int retryCount = 3; while (retryCount-> 0) { try { response = apiService.getData().execute(); if (response.isSuccessful()) break; } catch (IOException e) { // 记录错误,继续重试 } }