我正在使用Square's Tape library我遇到了一个要求,我基本上需要一个抽象的 TapeTask 类。但问题是 GsonConverter 的反序列化过程(它实现了库的 FileObjectQueue.Converter - 如 sample project 中所示)与接口(interface)/抽象类不能很好地配合。
我认为这是一个 Gson 反序列化问题,所以我使用自定义 TypeAdapter 注册了我的 Gson 实例,但这仍然没有解决问题。我认为它与 FileObjectQueue.Converter 有关。
我目前正在尝试通过子任务中的一个令人讨厌的包装回调接口(interface)来解决这个问题。
我的要求是拥有一个 TapeQueue 并且能够发送多种类型的任务。因此,我有一个 TapeTask 抽象类,并有具体的实现,例如 ImageDownloadTask、ImageUploadTask、UrlPostWithRetrofitTask、GoogleAnalyticsTrackerTask...等,所有这些都进入单个队列。
有没有办法实现这一点。我想我的问题可以归结为: 我需要做什么才能使 FileObjectQueue.Converter 与抽象类很好地配合?
提示:P:该类的javadoc说“..您还需要在序列化字节数组中包含具体的类名”但我不是确定这意味着什么。如果有人可以发布关于如何将名称包含在序列化字节数组中的解释,以实现我的目的,我将不胜感激!
最佳答案
我继续编写了一个抽象 Gson 转换器。我不认为它非常高效,但可以完成工作:
/**
* Use GSON to serialize classes to a bytes.
*
* This variant of {@link GsonConverter} works with anything you throw at it.
* It is however important for Gson to be able to understand your inner complex objects/entities
* Use an {@link InterfaceAdapter} for these purposes.
*
*/
public class GsonAbstractClassConverter<T>
implements FileObjectQueue.Converter<T> {
public static final String CONCRETE_CLASS_NAME = "concrete_class_name";
public static final String CONCRETE_CLASS_OBJECT = "concrete_class_object";
private final Gson _gson;
public GsonAbstractClassConverter(Gson gson) {
_gson = gson;
}
@Override
public T from(byte[] bytes) {
Reader reader = new InputStreamReader(new ByteArrayInputStream(bytes));
JsonObject completeAbstractClassInfoAsJson = _gson.fromJson(reader, JsonObject.class);
Class<T> clazz;
try {
String className = completeAbstractClassInfoAsJson.get(CONCRETE_CLASS_NAME).getAsString();
clazz = (Class<T>) Class.forName(className);
} catch (ClassNotFoundException e) {
Timber.e(e, "Error while deserializing TapeTask to a concrete class");
return null;
}
String objectDataAsString = completeAbstractClassInfoAsJson.get(CONCRETE_CLASS_OBJECT)
.getAsString();
return _gson.fromJson(objectDataAsString, clazz);
}
@Override
public void toStream(T object, OutputStream bytes) throws IOException {
Writer writer = new OutputStreamWriter(bytes);
JsonObject completeAbstractClassInfoAsJson = new JsonObject();
completeAbstractClassInfoAsJson.addProperty(CONCRETE_CLASS_NAME, object.getClass().getName());
completeAbstractClassInfoAsJson.addProperty(CONCRETE_CLASS_OBJECT, _gson.toJson(object));
_gson.toJson(completeAbstractClassInfoAsJson, writer);
writer.close();
}
}
关于android - 使用 Square 的 Tape 库如何处理调用抽象类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24645299/