说我有这个API:
我想使用这个超级怪异的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
但是我需要在#18行中使用它们。 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
}
});
答案 0 :(得分:1)
而不是FutureCallback<JsonObject>
和FutureCallback<JsonArray>
,为什么不这样扩展这些:
public interface JsonObjectFutureCallback extends FutureCallback<JsonObject> { }
public interface JsonArrayFutureCallback extends FutureCallback<JsonArray> { }
然后你可以像这样调用你的方法:
sendRequest(ACTION_BALANCE, null, new JsonObjectFutureCallback() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// my code goes here
}
});
// OR just
sendRequest(ACTION_OPERATIONS, null, new JsonArrayFutureCallback() {
@Override
public void onCompleted(Exception e, JsonArray result) {
// my code goes here
}
});
答案 1 :(得分:1)
您可以使用泛型类型将FutureCallback<JsonObject>
和FutureCallback<JsonArray>
作为参数传递给同一方法。
您还需要知道T的类型,以便调用适当的req.as(JsonObject/JsonArray)()
方法。不幸的是,java泛型主要是编译时间,因此类型信息在运行时丢失。您可以通过将额外的Class参数传递给您的方法来绕过它。
所以sendRequest方法应如下所示:
private <T>void sendRequest(String action, JsonObject params, FutureCallback<T> callback, Class<?> type) {
// body of the method
if(type == JsonObject.class) {
req.asJsonObject().setCallback(callback);
}
else if(type == JsonArray.class) {
req.asJsonArray().setCallback(callback);
}
}
你可以像这样调用你的方法:
sendRequest(ACTION_BALANCE, null, new FutureRequest<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// my code goes here
}
}, JsonObject.class);
// OR just
sendRequest(ACTION_OPERATIONS, null, new FutureRequest<JsonArray>() {
@Override
public void onCompleted(Exception e, JsonArray result) {
// my code goes here
}
}, JsonArray.class);