You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Retrofit+Gson解析JSON时TextView赋值返回Null求助

解决Retrofit+Gson解析JSON时TextView赋值为Null的问题

嗨,我看了你遇到的问题——用Retrofit+Gson解析JSON给TextView赋值时拿不到值,之前RecyclerView能成功解析,说明你对Retrofit的基本用法已经摸熟了,只是在单个响应的结构处理上踩了几个小坑,我帮你梳理一下:

核心错误点分析

你现在的问题根源在于Model类和JSON响应的结构完全不匹配,加上解析逻辑的小失误,导致拿不到ActualPrice的值:

  1. 你的JSON响应外层包含status、response_code和一个数组类型的result,但你的ItemDescriptionModel直接把数组里的字段(比如ActualPrice)放在了根层级,完全没对应外层的结构。
  2. 你在代码里调用model.getResult(),但你的ItemDescriptionModel里根本没有这个方法,这肯定会导致空指针或者无法获取数据。
  3. 用Call<JsonObject>再手动转Gson属于多此一举,Retrofit的Gson转换器可以直接帮你把响应解析成自定义类,减少出错概率。

修正步骤&完整代码

第一步:创建外层响应类

先定义一个对应JSON外层结构的类,用来包裹整个响应:

public class ItemDescriptionResponse {
    @SerializedName("status")
    private String status;
    @SerializedName("response_code")
    private int responseCode;
    @SerializedName("result")
    private List<ItemDescriptionModel> result;

    // Getter和Setter方法
    public String getStatus() { return status; }
    public void setStatus(String status) { this.status = status; }
    public int getResponseCode() { return responseCode; }
    public void setResponseCode(int responseCode) { this.responseCode = responseCode; }
    public List<ItemDescriptionModel> getResult() { return result; }
    public void setResult(List<ItemDescriptionModel> result) { this.result = result; }
}

第二步:修正ItemDescriptionModel

让这个类只对应result数组里的单个对象字段,SerializedName要和JSON里的键完全一致:

public class ItemDescriptionModel {
    @SerializedName("ActualPrice")
    private String actualPrice;
    @SerializedName("ProductName")
    private String productName;
    @SerializedName("DefaultImage_url")
    private String defaultImageUrl;
    // 其他你需要的字段可以按需添加,比如MarketPrice等

    // Getter和Setter方法
    public String getActualPrice() { return actualPrice; }
    public void setActualPrice(String actualPrice) { this.actualPrice = actualPrice; }
    public String getProductName() { return productName; }
    public void setProductName(String productName) { this.productName = productName; }
    public String getDefaultImageUrl() { return defaultImageUrl; }
    public void setDefaultImageUrl(String defaultImageUrl) { this.defaultImageUrl = defaultImageUrl; }
}

第三步:修改Retrofit接口

把返回类型改成我们刚创建的外层响应类,不用再返回JsonObject:

public interface ItemDescriptionInterface {
    @GET("getProductDetailByProductId?ProductId=3")
    Call<ItemDescriptionResponse> getItemDescription();
}

第四步:修正Activity里的解析逻辑

直接用Retrofit解析后的对象,获取result数组里的第一个元素(因为你的JSON里数组只有一个对象):

private void GetItemDescription() {
    Retrofit retrofit2 = new Retrofit.Builder()
            .baseUrl(BASE_URL)
            .addConverterFactory(GsonConverterFactory.create())
            .build();
    ItemDescriptionInterface apiService = retrofit2.create(ItemDescriptionInterface.class);
    Call<ItemDescriptionResponse> call = apiService.getItemDescription();
    
    call.enqueue(new Callback<ItemDescriptionResponse>() {
        @Override
        public void onResponse(Call<ItemDescriptionResponse> call, Response<ItemDescriptionResponse> response) {
            if (response.isSuccessful() && response.body() != null) {
                List<ItemDescriptionModel> resultList = response.body().getResult();
                if (!resultList.isEmpty()) {
                    // 取数组里的第一个对象
                    ItemDescriptionModel model = resultList.get(0);
                    // 现在可以正确获取ActualPrice了
                    price.setText(model.getActualPrice());
                } else {
                    price.setText("暂无数据");
                }
            } else {
                price.setText("加载失败");
            }
        }

        @Override
        public void onFailure(Call<ItemDescriptionResponse> call, Throwable t) {
            String msg = (t.getMessage() == null) ? "请求失败!" : t.getMessage();
            Log.d("descriptionofproduct", msg);
            price.setText("错误: " + msg);
        }
    });
}

为什么之前的代码拿不到值?

之前你把整个JSON字符串直接转成ItemDescriptionModel,但这个Model的结构和JSON完全不匹配:JSON里的ActualPrice是在result数组的对象里,而你的Model直接把ActualPrice当成了根层级的字段,Gson自然找不到对应的值,所以返回null。加上你错误地调用了不存在的model.getResult()方法,这也是问题的关键。

现在按照上面的代码修改后,就能正确获取ActualPrice并赋值给TextView了。

内容的提问来源于stack exchange,提问作者James Edition

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:01:02