【问题标题】:JSON, Retrofit 2 and converters on AndroidAndroid 上的 JSON、Retrofit 2 和转换器
【发布时间】:2017-07-05 13:16:19
【问题描述】:

我正在尝试使用 Retrofit 从汇率 remote API 获取数据。

为了更精确,我不问如何返回数组列表...我只是想知道返回数组列表或使用改造转换器是否更好,以及改造转换器是否适合这种情况。

此 API 向我返回格式如下的 JSON:

{
  "success": true,
  "terms": "https://currencylayer.com/terms",
  "privacy": "https://currencylayer.com/privacy",
  "timestamp": 1487243354,
  "source": "USD",
  "quotes": {
    "USDAED": 3.672503,
    "USDAFN": 66.599998,
    "USDALL": 127.501996,
    "USDAMD": 486.119995,
    "USDANG": 1.769648,
    "USDAOA": 165.082001,
    "USDARS": 15.37279,
    "USDAUD": 1.299101,
    "USDAWG": 1.8017,
    "USDAZN": 1.729104,
    "USDBAM": 1.842499,
    "USDBBD": 2,
    "USDBDT": 79.249746,
    "USDBGN": 1.853047,
    ...
    }
}

我使用这个网站jsonschema2pojo 从 JSON 数据创建我的对象。它为我创建了两个类ExampleQuotes。我的Quotes 类看起来像这样:

public class Quotes {

    @SerializedName("USDAED")
    @Expose
    private Double uSDAED;
    @SerializedName("USDAFN")
    @Expose
    private Double uSDAFN;
    @SerializedName("USDALL")
    @Expose
    private Double uSDALL;
    @SerializedName("USDAMD")
    @Expose
    private Double uSDAMD;
    @SerializedName("USDANG")
    @Expose
    private Double uSDANG;
    @SerializedName("USDAOA")
    ...
}

Example 类只包含一种方法来检索Quotes,调用 getQuotes() 返回一个包含所有引号的 Quotes 对象。然后我必须调用我的 Quotes 类的 getter() 来获取汇率。问题是我希望有一个方法可以返回列表中的所有引号,而不必调用所有 getter...当然,我可以轻松地在 Example 类中修改方法或在其他方式不同。无论如何,我想知道最好的方法是什么,我的意思是就良好实践而言,我使用带有 Dagger 2 的 MVP 架构。我听说过带有 Retrofit 的自定义转换器,它在这种特定情况下是否有用和合适?顺便说一句,如果您有关于 Retrofit 自定义转换器的良好(可理解)链接,请随时分享......我正在做这个项目是为了教育目的,所以请不要向我推荐另一个 API,我想像这样实现它,使用此 API。

public class Example {

    @SerializedName("success")
    @Expose
    private Boolean success;
    @SerializedName("terms")
    @Expose
    private String terms;
    @SerializedName("privacy")
    @Expose
    private String privacy;
    @SerializedName("timestamp")
    @Expose
    private Integer timestamp;
    @SerializedName("source")
    @Expose
    private String source;
    @SerializedName("quotes")
    @Expose
    private Quotes quotes;

    public Boolean getSuccess() {
        return success;
    }

    public void setSuccess(Boolean success) {
        this.success = success;
    }

    public String getTerms() {
        return terms;
    }

    public void setTerms(String terms) {
        this.terms = terms;
    }

    public String getPrivacy() {
        return privacy;
    }

    public void setPrivacy(String privacy) {
        this.privacy = privacy;
    }

    public Integer getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Integer timestamp) {
        this.timestamp = timestamp;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public Quotes getQuotes() {
        return quotes;
    }

    public void setQuotes(Quotes quotes) {
        this.quotes = quotes;
    }

}

【问题讨论】:

  • 也发布您的示例课程。
  • 嘿,如果您希望引号中的所有条目都作为数组列表,为什么不将引号对象更改为字符串数组列表。我说的是从重组你的 JSON 结构开始。这样您就不需要自定义适配器或其他东西
  • 它不能是字符串的arrayList它是map
  • 刚刚添加了我的示例类。正如我所写,我使用 Retrofit 框架。正如我在我的问题中所写的那样,我确定我可以将我的方法更改为拥有一个 Arraylist,但我只是想知道这是否是最好的方法,比如更好地使用 Retrofit 转换器。我不问如何以简单的方式解决这个问题,而是以正确的方式,如果正确的方式是返回一个列表,我可以做到。但我只想知道它是否是最好的。如果我在更大的项目中使用同样糟糕的方式做事,最好使用最佳实践,因为我刚刚开始使用这个 Retrofit,而不是做一些快速的代码并到处乱七八糟。

标签: android json converter retrofit mvp


【解决方案1】:

我终于找到了最简单的解决方案,因为没有人回答我关于改造转换器的问题,而且我投了反对票,我想我的问题很愚蠢。

我使用自定义 Quote 类而不是 HashMap 以防我以后想向我的类添加更多信息。

public class Quotes {

    @SerializedName("USDAED")
    @Expose
    private Double uSDAED;
    @SerializedName("USDAFN")
    @Expose
    private Double uSDAFN;
    @SerializedName("USDALL")
    @Expose
    private Double uSDALL;
    ...
     public List<Quote> getAllQuotes() {
        List<Quote> allQuotes = new ArrayList<>();

        allQuotes.addAll(Arrays.asList(
                new Quote("USDAED", new BigDecimal(uSDAED, MathContext.DECIMAL32)),
                new Quote("USDAFN", new BigDecimal(uSDAFN, MathContext.DECIMAL32)),
                new Quote("USDALL", new BigDecimal(uSDALL, MathContext.DECIMAL32)),
                new Quote("USDAMD", new BigDecimal(uSDAMD, MathContext.DECIMAL32)),
        ...
        new Quote("USDZMW", new BigDecimal(uSDZMW, MathContext.DECIMAL32)))

        );
        return allQuotes;
    }
    ...
}

MainActivity.java

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((App) getApplication()).getComponent().inject(this);

        String apiKey = getResources().getString(R.string.API_KEY);
        Call<Example> call = apiLayerForexAPI.getQuotes(apiKey);

        call.enqueue(new Callback<Example>() {
            @Override
            public void onResponse(Call<Example> call, Response<Example> response) {
                List<Quote> allQuotes = response.body().getQuotes().getAllQuotes();
                for(Quote q : allQuotes){
                    Log.d(LOG_TAG, q.toString());
                }

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-04-10
    • 2016-05-31
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多