[英]How to parse JSON array while using Spotify APIs?
在使用 Spotify 搜索 API 時,我想收到一張專輯列表。 然而,總是有一個錯誤,它期望一個數組但得到一個 object。 但是在我的代碼中,我只將類型設置為數組。 所以我不知道我哪里錯了。
這是 Spotify 文檔- https://developer.spotify.com/documentation/web-api/reference/search/search/
主要活動(我從 loginactivity 獲得 static TOKEN)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSearchEditText = findViewById(R.id.search_edittext);
mSearchButton = findViewById(R.id.search_button);
mTestTextView = findViewById(R.id.test_textview);
mAlbumList = new ArrayList<>();
mAlbum = new Album();
retrofitOperations();
mSearchButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mSearchEditText.getText() != null) {
searchForArt(mSearchEditText.getText().toString());
}
}
});
}
private void searchForArt(String text) {
text = text.replace(" ", "&20");
HashMap<String, String> parameters = new HashMap<>();
parameters.put("Authorization", "Bearer " + TOKEN);
Call<Album> call = mSpotifyService.getAlbum(text, "album", parameters);
Log.d(TAG, "searchForArt: started call");
call.enqueue(new Callback<Album>() {
@Override
public void onResponse(@NonNull Call<Album> call, @NonNull Response<Album> response) {
if (!response.isSuccessful()) {
Toast.makeText(MainActivity.this, "Response not successful", Toast.LENGTH_SHORT).show();
Log.d(TAG, "onResponse: not successful");
return;
}
Log.d(TAG, "onResponse: successful");
mTestTextView.setText(null);
mAlbum = response.body();
//for (Album album : mAlbumList) {
List<Item> itemList = mAlbum.getItemList();
for (Item item : itemList) {
List<Image> imageList = item.getImageList();
for (Image image : imageList) {
mTestTextView.append(image.getUrl() + "\n");
}
}
// }
}
@Override
public void onFailure(Call<Album> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "onFailure: call failure " + t.getMessage());
}
});
}
private void retrofitOperations() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.spotify.com/v1/")
.addConverterFactory(GsonConverterFactory.create())
.build();
mSpotifyService = retrofit.create(SpotifyService.class);
}
Spotify服務接口
public interface SpotifyService {
@GET("search")
Call<Album> getAlbum(@Query("q") String q,
@Query("type") String type,
@HeaderMap Map<String,String> headers);
}
專輯 class
public class Album implements Parcelable {
@SerializedName("items")
private List<Item> itemList;
public Album() {
}
public List<Item> getItemList() {
return itemList;
}
protected Album(Parcel in) {
itemList = in.createTypedArrayList(Item.CREATOR);
}
public static final Creator<Album> CREATOR = new Creator<Album>() {
@Override
public Album createFromParcel(Parcel in) {
return new Album(in);
}
@Override
public Album[] newArray(int size) {
return new Album[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeTypedList(itemList);
}
}
項目 class
public class Item implements Parcelable {
@SerializedName("images")
private List<Image> imageList;
public Item() {
}
public List<Image> getImageList() {
return imageList;
}
public void setImageList(List<Image> imageList) {
this.imageList = imageList;
}
protected Item(Parcel in) {
}
public static final Creator<Item> CREATOR = new Creator<Item>() {
@Override
public Item createFromParcel(Parcel in) {
return new Item(in);
}
@Override
public Item[] newArray(int size) {
return new Item[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
}
}
圖片 class
public class Image implements Parcelable{
@SerializedName("url")
private String url;
public Image() {
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
protected Image(Parcel in) {
url = in.readString();
}
public static final Creator<Image> CREATOR = new Creator<Image>() {
@Override
public Image createFromParcel(Parcel in) {
return new Image(in);
}
@Override
public Image[] newArray(int size) {
return new Image[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(url);
}
}
錯誤
2020-04-07 17:57:55.945 21128-21128/com.example.spotify_album_art E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.spotify_album_art, PID: 21128
java.lang.NullPointerException: Attempt to invoke interface method 'java.util.Iterator java.util.List.iterator()' on a null object reference
at com.example.spotifyalbumart.MainActivity$2.onResponse(MainActivity.java:96)
at retrofit2.ExecutorCallAdapterFactory$ExecutorCallbackCall$1$1.run(ExecutorCallAdapterFactory.java:70)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
您在 API 通話中收到的回復存在問題。 在 API 中,它只返回您的Album
class 的 object 而不是List<Album>
。
所以就像下面這樣是對 API 的請求。
Call<Album> call = mSpotifyService.getAlbum(text, "album", parameters);
Log.d(TAG, "searchForArt: started call");
call.enqueue(new Callback<Album>() {
@Override
public void onResponse(Call<Album> call, Response<Album> response) {
}
@Override
public void onFailure(Call<Album> call, Throwable t) {
Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
Log.d(TAG, "onFailure: call failure "+t.getMessage());
}
});
在你的界面中
@GET("search")
Call<Album> getAlbum(@Query("q") String q,
@Query("type") String type,
@HeaderMap Map<String,String> headers);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.