如何通过 Retrofit 使用 Soundcloud API 中的分页 URL

How to work with pagination URL from Soundcloud API with Retrofit

我正在使用 Retrofit 从 Soundcloud 获取曲目列表-API。 请求导致带有曲目列表的回调 - 没有分页这有效。 但是当我将分页参数 (linked_partitioning=1) 添加到请求时,改造 returns 一个错误。我不知道如何编写回调类型来获取 URL-String 到下一页和我的列表结果。

改装电话:

Map<String, String> queryMap = new HashMap<String, String>();
queryMap.put("client_id" , My_Config.CLIENT_ID);
queryMap.put("tag", "loop" );
queryMap.put("license", "cc-by-sa" ); 
queryMap.put("limit", "10"); 

// This is causing  a different Return Type ---> ERROR
queryMap.put("linked_partitioning", "1" ); 

scService = RetrofitRestAdapter.getService();
scService.searchTracks(queryMap, callback); // callback function success  is not reached because of the ERROR

GET 请求的接口:

@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<List<My_Track>> cb);

改造回调:

Callback<List<My_Track>> callbackTracks = new Callback<List<My_Track>>() {
    @Override
    public void success(List<My_Track> tracks, Response response) {...}
    @Override
    public void failure(RetrofitError error) {...}
};

改造异常:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

编辑: Soundcloud 的结果模式 API:

没有分页结果是一个 Array/List 的 Track-Elements,看起来像这样:

[{"download_url":null,"key_signature":"","user_favorite":false,...},
{...},{...}]

分页结果是一个元素包含一个集合加上一个next_href:

{"collection":[
{"download_url":null,"key_signature":"",...},
{...},
{...}
],"next_href":"https://..."}  

如何声明 Callback 的返回类型以将 Collection-Array 和 "next_href" 与 Result 分开?

谢谢!

根据您提供的错误,我可以猜测,在您请求分页后,API returns 生成的是对象而不是数组。例如,在使用分页之前,结果会像

[
   {
      item 1,
      item 2
   },
   {
      item 1,
      item 2
   }

]

使用分页后,结果会是这样

{
   page: 1,
   count: 400,
   results: [
       {
          item 1,
          item 2
       }, 
       {
          item 1,
          item 2
       }
   ]
}

因此您可能需要更改分页映射。 (由于您没有提供结果模式,所以我认为这是您错误的原因)

编辑答案

目前您正在将返回的 JSON 映射到 My_Track class 的列表中。现在您需要创建另一个 class 用于映射,并将 My_Track 的列表声明为 属性。示例:

public class MyTrackHolder {
    public final String next_href;
    public final List<My_Track> collection;

    public MyTrackHolder(final String next_href, final List<My_Track> collection)
    {
        this.next_href = next_href;
        this.collection = collection;
    }

}

你的界面会像

@GET("/tracks")
public void searchTracks(@QueryMap Map<String, String> filters, Callback<MyTrackHolder> cb);

最后调用这个接口方法如下

Callback<MyTrackHolder> callbackTracks = new Callback<MyTrackHolder>() {
    @Override
    public void success(MyTrackHolder trackHolder, Response response) {...}
    @Override
    public void failure(RetrofitError error) {...}
};

您可以使用

检索曲目
List<My_Track> tracks = trackHolder.collection;