当前位置:首页 > 行业动态 > 正文

安卓从服务器获取json数据

安卓应用配置网络权限,通过OkHttp/Retrofit异步请求服务器JSON数据,Gson解析为对象并处理异常,验证数据后于主线程更新UI

前置准备

添加网络权限

AndroidManifest.xml 中声明网络访问权限:

<uses-permission android:name="android.permission.INTERNET" />

选择网络库

  • 原生 APIHttpURLConnection(轻量但代码较多)
  • 第三方库OkHttp(简洁高效)、Retrofit(适合复杂 API 调用)
  • JSON 解析库org.json(内置)、Gson(Google 出品)、Moshi(现代化)

实现步骤(以 OkHttp + Gson 为例)

添加依赖

build.gradle 中添加:

implementation 'com.squareup.okhttp3:okhttp:4.10.0'
implementation 'com.google.code.gson:gson:2.10.1'

创建数据模型类

假设 JSON 数据格式为:

{
  "name": "张三",
  "age": 25,
  "hobbies": ["篮球", "阅读"]
}

对应 Java 类:

public class User {
    private String name;
    private int age;
    private List<String> hobbies;
    // Getter 和 Setter 方法
}

发起网络请求

import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import com.google.gson.Gson;
import java.io.IOException;
public class JsonFetcher {
    private static final String URL = "https://example.com/api/user";
    public void fetchData() {
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(URL)
                .build();
        client.newCall(request).enqueue(new okhttp3.Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 处理失败(如网络错误)
                runOnMainThread(() -> {
                    // 更新 UI 或日志
                    Log.e("NetworkError", e.getMessage());
                });
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (response.isSuccessful()) {
                    String jsonData = response.body().string();
                    parseJson(jsonData);
                } else {
                    // 处理 HTTP 错误(如 404)
                    runOnMainThread(() -> {
                        Log.e("HTTPError", "Code: " + response.code());
                    });
                }
            }
        });
    }
    private void parseJson(String json) {
        Gson gson = new Gson();
        User user = gson.fromJson(json, User.class);
        runOnMainThread(() -> {
            // 更新 UI(如设置 TextView)
            textView.setText(user.getName() + ", 年龄:" + user.getAge());
        });
    }
    private void runOnMainThread(Runnable task) {
        new Handler(Looper.getMainLooper()).post(task);
    }
}

关键问题处理

问题 解决方案
主线程网络请求崩溃 使用子线程(如 AsyncTaskThread)或异步框架(如 RxJava、协程)
JSON 解析失败 检查字段名是否匹配,使用 @SerializedName 注解处理命名不一致问题
SSL 证书验证失败 在 OkHttp 中配置 sslSocketFactory,或调试时临时禁用验证(不推荐生产环境)
乱码问题 确保服务器返回 UTF-8 编码,客户端也按 UTF-8 解析

常见问题与解答

问题 1:如何发送带参数的 POST 请求?

解答
修改 Request.Builder 并添加请求体:

MediaType JSON = MediaType.get("application/json; charset=utf-8");
String postBody = new Gson().toJson(new User("李四", 30, null)); // 构造 JSON
Request request = new Request.Builder()
        .url("https://example.com/api/user")
        .post(RequestBody.create(postBody, JSON))
        .build();

问题 2:如何解析嵌套 JSON 对象?

解答
定义嵌套类或使用 @SerializedName

public class User {
    private String name;
    @SerializedName("profile") // 对应 JSON 中的 profile 对象
    private Profile profile;
    // 其他字段和 Getter/Setter
}
public class Profile {
    private String city;
    private String phone;
    // Getter/Setter
}

扩展优化建议

优化方向 说明
缓存数据 使用 OkHttp 的缓存机制或集成 Room 数据库存储数据
错误重试机制 通过拦截器(Interceptor)实现自动重试
安全性 使用 HTTPS,配置证书锁定(Certificate Pinning)
性能优化 使用 Kotlin 协程替代回调,简化异步逻辑
0