Retrofit是一个很棒的库,易于使用和维护,但是我的情况有所不同,众所周知,我们应该应用创建改造api的阶段并做出相应的响应,
改造实例:
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(new ErrorCallAdapter.MyCallAdapterFactory())
.client(httpClient)
.build();
return retrofit;
API接口:
@GET("api/getTheResults")
ErrorCallAdapter.MyCall<GeneralResponse<SomeEntity> getGenericMethod();
ErrorCallAdapter的一部分:
@Override
public void enqueue(final MyCallback<Object> callback) {
call.enqueue(new Callback<GeneralResponse<T>>() {
@Override
public void onResponse(final Call<GeneralResponse<T>> call, final Response<GeneralResponse<T>> response) {
final int code = response.code();
mainHandler.post(new Runnable() {
@Override
public void run() {
if (response.isSuccessful()) {
if (response.body().getStatus() == 1) {
callback.onResult(response.body().getResponse());
} else
callback.onError(response.body().getMError());
} else
callback.onError(new MError(code,
response.message() != null ? response.message() : "onResponse error"));
}
});
}
@Override
public void onFailure(Call<GeneralResponse<T>> call, Throwable t) {
if (t != null)
callback.onError(new MError(501,
t.getMessage() != null ? t.getMessage() : "unexpected error"));
else
callback.onError(new MError(501,
"unexpected error"));
}
});
}
获取数据的一部分:
public void loadUserSetupData() {
ErrorCallAdapter.MyCall<GeneralResponse<Data>, Data> DataCall = apiManager.getData();
setupDataMyCall.enqueue(new ErrorHandlingCallAdapter.MyCallback<Data>() {
@Override
public void onResult(Data data) {
endProgressDialog();
apiResult.onSuccess(data);
}
@Override
public void onError(MError mError) {
endProgressDialog();
apiResult.onError(mError.getErrorMessage(mContext));
}
});
}
我尝试获取的数据为JSON格式,
{
"Status": 1,
"Error": null,
"ResponseList": [
{
"ErCode": 0,
"Masseg": null,
"DType": "OnceData",
"Contents": {
"VList": [{
"name":"name"
"name":"name"
"name":"name"
}],
"WList": [{
"name":"name"
"name":"name"
"name":"name"
}, {
"name":"name"
"name":"name"
"name":"name"
}],
"UList": [{
"name":"name"
"dd":"ddd" "DobledataType"
"object":"name" "object data type"
}, {
"name":"name"
"int":"1"
"code":"15.00" "float data type
}],
}
}
]
}
“上面,我将“名称”称为实体对象(UList,VList和WList中的每个都是仅用于说明的对象)。
我的问题是:如何使改装适用于任何类型的数据,无论哪种类型它都会获取对象,这意味着我不知道“目录”列表是否具有特定类型的对象,我想要使其工作在我不知道对象的情况下可以接收任何类型的任何类型的情况下,我们可以指定味精DType(以前知道DType = data例如将执行某些操作),但是我们不知道是响应对象的类型(字符串,对象,整数或仅一个字符串的数组列表) 我们如何在Android改装中做到这一点?
答案 0 :(得分:2)
如果您根本不知道“ Contents”字段的内容是什么,则可以将其直接设置为模型中的JSONObject,但是每次您要检索某些内容时都必须做一些工作在内容字段中。
但是,如果您知道它可以有什么类型,例如,您确定它可以是String数组,String或int类型,则可以使用自定义GSON deserializer。
首先,您必须更改Model / Pojo以处理每种类型,例如:
abstract class Model {
// put here all the fields you know the type is stable
}
// for when content is a list
public class ListModel extends Model {
@SerializedName("Contents")
List<String> content;
}
// for when content is a String
public class StringModel extends Model {
@SerializedName("Contents")
String content;
}
// add every other derived class you need for the other types that the content field can have
现在您可以创建一个反序列化器,它将返回正确的Model对象:
public class ModelDeserializer implements JsonDeserializer<Model> {
@Override
public Model deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
// get the "contents" field
JsonElement contents = jsonObject.get("Contents");
if (contents != null) {
if (contents.isJsonArray()) { // if this is a list, parse as ListModel
return context.deserialize(jsonObject,
ListModel.class);
}
if (contents.isJsonPrimitive()) { // json primitives are number, string, bool, character
if (contents.getAsJsonPrimitive().isString() {
return context.deserialize(jsonObject, StringModel.class);
}
}
// do the same for every other type you might have
}
return null;
}
}
最后,您必须告诉Retrofit和Gson使用该反序列化器:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Model.class, new ModelDeserializer())
.create();
// just add the new gson object to your converterfactory
retrofit = new Retrofit.Builder()
.baseUrl(url)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(new ErrorCallAdapter.MyCallAdapterFactory())
.client(httpClient)
.build();
return retrofit;
它应该可以工作。