假设我有这个 API:
- 需要很多认证的东西。
- 总是返回 JSON,但有时返回一个对象,有时返回一个数组。但是,很容易预测将返回什么。
我想使用这个超级棒的Ion 库(由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);
}
这很好用,直到我需要收到一个请求,而不是 a JsonObject
is a 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
, - 我可以使用另一个参数来指定类型,然后将 my
callback
转换为FutureRequest<JsonObject>
orFutureRequest<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
}
});