【问题标题】:Android: How to get object attribute from List<Class> using RetrofitAndroid:如何使用 Retrofit 从 List<Class> 获取对象属性
【发布时间】:2018-07-16 20:12:30
【问题描述】:

请帮我解决这个问题。我想通过 REST API 从 JSON 对象中获取一些数据。

这里是json的演示:

{
"itemList": [
    {
        "name": "AF1_AC",
        "value": false,
        "awid": "1",
        "sys": {
            "cts": "2018-07-16T14:51:34.166Z",
            "mts": "2018-07-16T17:49:40.206Z",
            "rev": 775
        },
        "id": "5b4cb0f66a4c333860d64d79"
    },
    {
        "name": "ST1_RE",
        "value": 27.11,
        "awid": "1",
        "sys": {
            "cts": "2018-07-15T14:53:05.228Z",
            "mts": "2018-07-16T17:49:40.320Z",
            "rev": 4124
        }
    }
    ]
}

这是我的界面:

public interface FarmAPI {

String BASE_URL = "http://10.0.2.2:6221/";

@GET("smartfarm/0-1/listFarmObjectValue") Call<ItemList> getItemList();

class Factory {
    private static FarmAPI service;

    public static FarmAPI getInstance() {
        if (service == null) {
            HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
            interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
            OkHttpClient client = new OkHttpClient.Builder().
                    addInterceptor(interceptor)
                    .build();
            Retrofit retrofit = new Retrofit.Builder()
                    .addConverterFactory(GsonConverterFactory.create())
                    .baseUrl(BASE_URL)
                    .client(client).build();
            service = retrofit.create(FarmAPI.class);
            return service;
        } else {
            return service;
        }
    }
}

}

这是由 jsonschema2pojo 生成的类:

public class ListFarmObjectValue {

@SerializedName("itemList")
@Expose
private List<ItemList> itemList = null;

public List<ItemList> getItemList() {
    return itemList;
}

public void setItemList(List<ItemList> itemList) {
    this.itemList = itemList;
}

}

第二个:

public class ItemList {

@SerializedName("name")
@Expose
private String name;
@SerializedName("value")
@Expose
private double value;
@SerializedName("awid")
@Expose
private String awid;

@SerializedName("id")
@Expose
private String id;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public double getValue() {
    return value;
}

public void setValue(double value) {
    this.value = value;
}

public String getAwid() {
    return awid;
}

public void setAwid(String awid) {
    this.awid = awid;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

}

现在我想从对象中获取值,其中 name = ST1_RE 并将值设置为特定的 TextView。在 onCreate 方法中:

FarmAPI.Factory.getInstance().getItemList().enqueue(new Callback<ItemList>() {
        @Override
        public void onResponse(Call<ItemList> call, Response<ItemList> response) {
            if (response.body().getName().equals("ST1_RE")) {
                realTemperature.setText(response.body().getValue() + "");
            }
        }

        @Override
        public void onFailure(Call<ItemList> call, Throwable t) {
            t.printStackTrace();
        }
    });

但它不起作用:( 你能告诉我在这种情况下我该怎么做吗?或者如果更好的话,也许不通过 jsonschema2pojo 生成类......?我看到了一些例子,但它对我来说是新的类别,我不明白。而且我不想更改 FarmAPI 接口,因为我在其他情况下使用它。

非常感谢!

【问题讨论】:

    标签: android json list retrofit


    【解决方案1】:

    1) 更改 API 调用的预期类型

    @GET("smartfarm/0-1/listFarmObjectValue") Call&lt;ItemList&gt; getItemList();

    @GET("smartfarm/0-1/listFarmObjectValue") Call&lt; ListFarmObjectValue &gt; getItemList();

    2)遍历 ItemList 对象列表以找到名称为“ST1_RE”的对象

    FarmAPI.Factory.getInstance().getItemList().enqueue(new Callback<ListFarmObjectValue>() { @Override public void onResponse(Call<ListFarmObjectValue> call, Response<ListFarmObjectValue> response) { ListFarmObjectValue value = response.body(); for(ItemList item : value.getItemList()){ if (item.getName().equals("ST1_RE")) { realTemperature.setText(response.body().getValue() + ""); break; } } } });

    编辑: 我刚刚看到您不想更改 API 调用的消息。在这种情况下,只需在同一个类中使用我提到的新返回类型创建一个新方法。

    【讨论】:

    • 非常感谢您的快速回复,但它不起作用。我改变了 realTemperature.setText(response.body().getValue() + "");到 realTemperature.setText(item.getValue() + "");但 TextView 不会改变。但是在控制台中,有正确的数据。生成的类可能有问题。你能告诉我如何用我自己为这个json创建的类来做到这一点吗?谢谢!
    • 在 onRespose() 方法中放置一个 Debug 点,看看它是否按预期经历了所有情况。另外,看看它是否不是像 TextView 这样的 UI 问题,由于某些原因不可见。将硬编码文本设置为文本视图,以确认 UI 中一切正常。
    • 跳转到onFailure方法。我看到异常: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected a double but was BEGIN_OBJECT at line 1 column 40 path $.itemList[0].value 看来我不能有布尔值,也不能加倍。但是在 json 中有两种类型的值——布尔值和双精度值。请问有什么方法可以做到吗?谢谢
    • 您可以将 'value' 类型设为 'Object' 而不是 'double',并且可以在使用 'instanceof' 检查类型后适当地转换它。但是你只能转换为 Double 或 Boolean,而不是原始的 double/boolean。
    猜你喜欢
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2014-07-16
    • 1970-01-01
    • 2022-01-21
    • 2014-01-04
    • 1970-01-01
    • 2016-04-09
    相关资源
    最近更新 更多