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 Example
和 Quotes
。我的 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();
}
});
}
我正在尝试使用 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 Example
和 Quotes
。我的 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();
}
});
}