【发布时间】:2014-11-03 14:02:13
【问题描述】:
我正在尝试重构我的代码,以便将 Retrofit(来自 Volley)用于一些 Foursquare API 调用,但没有找到一个合适的示例来说明如何指定一个查询参数,该参数具有用逗号分隔的 2 个值。
我的基本网址如下:
public static final String VENUES_BASE_URL = "https://api.foursquare.com/v2/venues";
我的网址的其余部分是这样的:
"?ll=40.7,50.2&limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx";
我的界面的第一个实现:
public interface Fourquare {
@GET("/explore?ll={p1},{p2}&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx")
Response getVenues(@Path("p1") String param1,
@Path("p2") String param2);
}
然后发出这样的请求:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ConfigConstants.VENUES_BASE_URL)
.build();
Fourquare fourquare = restAdapter.create(Fourquare.class);
Response myResponse = fourquare.getVenues("50", "75");
但是,上面给了我以下错误:
retrofit.RetrofitError: Fourquare.getVenues: URL query string "ll={p1},{p2}&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx" must not have replace block.
第二次实现(在查看了一些使用查询参数的 SO 响应之后。注意:一旦我弄清楚 ll? 参数调用,我将把令牌作为参数):
@GET("/explore&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx")
void getVenues(@Query("ll") String ll,
Callback<String> cb);
实际调用如下:
fourquare.getVenues("50,75", new Callback<String>() {
@Override
public void success(String s, Response response) {
Log.d(TAG, "Successful run!");
}
@Override
public void failure(RetrofitError error) {
Log.d(TAG, "Failed run!");
}
});
通过上述实现,failure() 方法总是被调用,所以我的代码仍然有问题。有人可以就执行此调用的正确方法提出一些建议吗?我很确定问题出在“ll?”上。范围。
更新: 开启日志记录后,这是我从 Retrofit 获得的最终网址: https://api.foursquare.com/v2/venues/explore&limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx?ll=30.26%2C-97.74
看起来 Foursquare 服务器不喜欢 url 末尾的 ?ll 参数,它必须明确放置在 ../v2/venues/explore 之后,因为当通过浏览器。
有什么解决方案可以从 API 中绕过这个限制?
第三次实施(2014 年 9 月 17 日) 借助 colriot 的建议,我能够解决以前实施时遇到的 400 响应代码。我仍然遇到 GSON 的速度问题,因此正在寻找有关如何解决该问题的建议。具体来说,与 Volley 相比,我的 Retrofit 实现需要更长的时间来显示我的结果,所以我想知道是否有更好的方法来实现回调。
四方界面
public interface Fourquare {
@GET("/explore?limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx")
void getVenues(@Query("ll") String ll,
Callback<Object> cb);
}
RestAdapter 调用
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(ConfigConstants.VENUES_BASE_URL)
.build();
Foursquare foursquare = restAdapter.create(Foursquare.class);
foursquare.getVenues("30.26,-97.74", new Callback<Object>() {
@Override
public void success(Object o, Response response) {
Log.d(TAG, "Success!");
// Parse response
GsonBuilder gsonBuilder = new GsonBuilder();
Gson gson = gsonBuilder.create();
JsonParser parser = new JsonParser();
String response2 = gson.toJson(o);
JsonObject data = parser.parse(response2).getAsJsonObject();
// Populate data model
MetaResponse metaResponse = gson.fromJson(data.get("meta"), MetaResponse.class);
VenuesExploreResponse myResponse = gson.fromJson(data.get("response"), VenuesExploreResponse.class);
// Store results from myResponse in List
}
@Override
public void failure(RetrofitError error) {
Log.d(TAG, "Failures!");
}
});
上述回调实现的当前问题是解析和显示结果需要比 Volley 更长的时间(大约 1 秒)。 GsonBuilder/Gson/JsonParser 块与我的 Volley onResponse(String response) 方法完全相同,除了那个中间“response2”对象,所以这个中间/额外步骤肯定是瓶颈。我正在寻找有关如何更好地实现 Gson 解析的建议。如果这可能更适合作为一个新的/单独的问题,我会这样做。
【问题讨论】:
标签: android foursquare retrofit