【发布时间】:2013-12-10 20:36:42
【问题描述】:
假设我有这个 API:
- 需要很多身份验证。
- 总是返回 JSON,但有时返回一个对象,有时返回一个数组。但是,很容易预测会返回什么。
我想用这个超级棒的Ion library(Koushik Dutta)。
作为我正在使用的 API,需要身份验证、为每个请求设置正确的标头等。我将以某种方式包装它,例如:http://goo.gl/5NLeQn
private void sendRequest(String action, JsonObject params, FutureCallback<JsonObject> callback) {
String nonce = "" + getNonce();
Builders.Any.B req = Ion.with(context, BASE_URL + action);
req.setBodyParameter("key", API_KEY)
.setBodyParameter("signature", getSignature(nonce))
.setBodyParameter("nonce", nonce);
if( params!=null ) {
for(Map.Entry<String, JsonElement> param : params.entrySet()) {
JsonElement el = param.getValue();
if( el.isJsonPrimitive() ) req.setBodyParameter(param.getKey(), el.getAsString());
}
}
req.asJsonObject()
.setCallback(callback);
}
这很好用,直到我需要收到一个请求,而不是 JsonObject 是 JsonArray:
java.lang.ClassCastException: com.google.gson.JsonArray 无法转换为 com.google.gson.JsonObject
因此,作为一种快速的解决方法,我可以创建两种方法将流重定向到一个共同点,但为了让这里的事情更容易,假设它看起来像这样: http://goo.gl/pzSal3.
private void sendRequest(String action, JsonObject params, FutureCallback<JsonObject> callback) {
String nonce = "" + getNonce();
Builders.Any.B req = Ion.with(context, BASE_URL + action);
req.setBodyParameter("key", API_KEY)
.setBodyParameter("signature", getSignature(nonce))
.setBodyParameter("nonce", nonce);
if( params!=null ) {
for(Map.Entry<String, JsonElement> param : params.entrySet()) {
JsonElement el = param.getValue();
if( el.isJsonPrimitive() ) req.setBodyParameter(param.getKey(), el.getAsString());
}
}
req.asJsonObject()
.setCallback(callback);
}
private void sendRequest(String action, JsonObject params, FutureCallback<JsonArray> callback) {
String nonce = "" + getNonce();
Builders.Any.B req = Ion.with(context, BASE_URL + action);
req.setBodyParameter("key", API_KEY)
.setBodyParameter("signature", getSignature(nonce))
.setBodyParameter("nonce", nonce);
if( params!=null ) {
for(Map.Entry<String, JsonElement> param : params.entrySet()) {
JsonElement el = param.getValue();
if( el.isJsonPrimitive() ) req.setBodyParameter(param.getKey(), el.getAsString());
}
}
req.asJsonArray()
.setCallback(callback);
}
但是接着BAM,又出现了一个错误:
'sendRequest(String, JsonObject, FutureCallback)' 与'sendRequest(String, JsonObject, FutureCallback)' 冲突;两种方法都有相同的擦除
似乎这些类型在运行时被剥离,VM 变得混乱。
我想出了一些“解决方案”:
- 我可以使用
FutureRequest而不声明类型,但是我需要它们在#18th 行。 - 我可以改用
String,然后用Gson解析它, - 我可以使用另一个参数来指定类型,然后将我的
callback转换为FutureRequest<JsonObject>或FutureRequest<JsonArray>
但所有这些似乎都只是一些廉价的技巧,可以让事情(以某种方式)工作。这里有人知道该问题的任何适当解决方案吗?
我最喜欢调用这些方法的方式是:
sendRequest(ACTION_BALANCE, null, new FutureRequest<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// my code goes here
}
});
// OR just
sendRequest(ACTION_OPERATIONS, null, new FutureRequest<JsonArray>() {
@Override
public void onCompleted(Exception e, JsonArray result) {
// my code goes here
}
});
【问题讨论】:
标签: java android api gson ion-koush