所以,我试图通过构建一个应用程序来学习android,其中我使用lastFm api来获取类似的歌曲。我将retrofit2与Gson和rxJava一起使用。
要读取json响应,我使用Pojo类。要首先获得类似的曲目,我必须搜索它(第一次api调用),然后我必须根据用户选择的api调用api。
有些POJO在这些来电之间很常见,所以我不必复制它们。
我的问题是,在第一次调用中,响应包含一个艺术家作为字符串(仅名称),而在第二个响应中,艺术家是一个对象。
显然,当我尝试阅读第一个回应时,Gson期待一个"艺术家"对象,但它得到一个字符串。我如何将它们都实现为一个POJO,作为" Track"?
这是我的代码,我希望我很清楚(当我试图解释时,我有一个问题......,好吧,我的问题)
public class Track implements Parcelable{
@SerializedName("name")
@Expose
private String name;
@SerializedName("playcount")
@Expose
private Integer mPlaycount;
@SerializedName("artist")
@Expose
private Artist artist; // If i make this a String, the first call works
@SerializedName("url")
@Expose
private String url;
@SerializedName("streamable")
@Expose
private Streamable streamable;
@SerializedName("listeners")
@Expose
private String listeners;
@SerializedName("match")
@Expose
private String match;
@SerializedName("image")
@Expose
private List<Image> image = new ArrayList<>();
@SerializedName("mbid")
@Expose
private String mbid;
@Expose
private String mediumImage;
// Getters, setter, parcelable methods etc.
JSon第一个响应示例(不是完整响应,只有一个结果) 响应来自lastFm api
{
"results": {
"opensearch:Query": {
"#text": "",
"role": "request",
"startPage": "1"
},
"opensearch:totalResults": "1637",
"opensearch:startIndex": "0",
"opensearch:itemsPerPage": "30",
"trackmatches": {
"track": [
{
"name": "Ich tu dir weh",
"artist": "Rammstein",
"url": "https://www.last.fm/music/Rammstein/_/Ich+tu+dir+weh",
"streamable": "FIXME",
"listeners": "198819",
"image": [
{
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "medium"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/174s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "large"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "extralarge"
}
],
"mbid": "1752a3db-918e-43ba-b7ac-63bcc9a6433c"
}
]
},
"@attr": {}
}
}
JSon第二个响应示例(不是完整响应,只有一个结果) 响应来自lastFm api
{
"similartracks": {
"track": [
{
"name": "Waidmanns Heil",
"playcount": 1806826,
"mbid": "e1e060e0-73e7-4939-ac80-635e8cba45a2",
"match": 1,
"url": "https://www.last.fm/music/Rammstein/_/Waidmanns+Heil",
"streamable": {
"#text": "0",
"fulltrack": "0"
},
"duration": 213,
"artist": {
"name": "Rammstein",
"mbid": "b2d122f9-eadb-4930-a196-8f221eeb0c66",
"url": "https://www.last.fm/music/Rammstein"
},
"image": [
{
"#text": "https://lastfm-img2.akamaized.net/i/u/34s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "small"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/64s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "medium"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/174s/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "large"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "extralarge"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
"size": "mega"
},
{
"#text": "https://lastfm-img2.akamaized.net/i/u/300x300/1a82cbe48f604d4c8325122b09d310ed.png",
"size": ""
}
]
}
],
"@attr": {
"artist": "Rammstein"
}
}
}
提前感谢您的回复。 附:堆栈中的第一个问题溢出...... yeeee!
答案 0 :(得分:0)
看起来类似的轨道对象在结构上与trackMatches对象不同。
我建议为SimilarTrack响应创建第二个类对象。
SimilarTrack会有一个Artist对象和一个Streamable对象
TrackMatches将Artist作为字符串并可流式化为字符串
答案 1 :(得分:0)
继承可以在这里使用......
为常见对象制作一个通用类 -
我正在考虑我的榜样 -
比如说,每个回复都会有一个共同的价值 - 那就是"status":"success"
我将制作一个基类 -
BaseResponse.java
public class BaseResponse {
@SerializedName("status")
@Expose
private String status;
}
我们可以扩展这个需要解析状态的类 -
像
public class ResponseOne extends BaseResponse {
@SerializedName("name_one")
@Expose
private String nameOne;
}
public class ResponseOne extends BaseResponse {
@SerializedName("name_two")
@Expose
private String nameTwo;
}
希望它有意义; - )
答案 2 :(得分:0)
解决方案是使用GSON的多态性功能。 This tutorial可能有所帮助。