使用Retrofit+Gson解析JSON时TextView赋值返回Null求助
解决Retrofit+Gson解析JSON时TextView赋值为Null的问题
嗨,我看了你遇到的问题——用Retrofit+Gson解析JSON给TextView赋值时拿不到值,之前RecyclerView能成功解析,说明你对Retrofit的基本用法已经摸熟了,只是在单个响应的结构处理上踩了几个小坑,我帮你梳理一下:
核心错误点分析
你现在的问题根源在于Model类和JSON响应的结构完全不匹配,加上解析逻辑的小失误,导致拿不到ActualPrice的值:
- 你的JSON响应外层包含
status、response_code和一个数组类型的result,但你的ItemDescriptionModel直接把数组里的字段(比如ActualPrice)放在了根层级,完全没对应外层的结构。 - 你在代码里调用
model.getResult(),但你的ItemDescriptionModel里根本没有这个方法,这肯定会导致空指针或者无法获取数据。 - 用
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
相关产品推荐
相关产品推荐

