JSON、Android 上的 Retrofit 2 和转换器

JSON, Retrofit 2 and converters on Android

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

只是为了更精确,我不问如何 return arraylist...我只是想知道 return arraylist 或使用 Retrofit 转换器是否更好,如果改装转换器适合这种情况。

这个 API return 给我一个 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 数据创建我的对象。它为我创造了两个 classes ExampleQuotes。我的 Quotes class 看起来像这样:

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 class 仅包含一种检索 Quotes 的方法,称为 getQuotes() returning 带有所有引号的 Quotes 对象。然后我必须调用 Quotes class 的 getter() 来获取汇率。问题是我想要一个方法 return 将列表中的所有引号都发送给我,而不必调用所有 getter s ...当然我可以轻松修改我的 Example class 中的方法或其他不同的方法。无论如何,我想知道什么是最好的方法,我的意思是就良好实践而言,我将 MVP 架构与 Dagger 2 一起使用。我听说过带有 Retrofit 的自定义转换器,它在这种特定情况下是否有用和合适?顺便说一下,如果您对 Retrofit 自定义转换器有很好的(可以理解的)link,请随时分享...我做这个项目是为了教育目的,所以请不要再给我推荐 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;
    }

}

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

我使用自定义报价单 class 而不是 HashMap 以防万一我以后想向我的 Class 添加更多信息。

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();
            }
        });
    }