2

我正在使用Square 的 Tape 库,并且我遇到了一个基本上需要一个抽象 TapeTask 类的要求。但问题是 GsonConverter 的反序列化过程(它实现了库的 FileObjectQueue.Converter - 如示例项目中所示)不能很好地与接口/抽象类一起使用。

我认为这是一个 Gson 反序列化问题,所以我使用自定义 TypeAdapter 注册了我的 Gson 实例,但这仍然无法解决问题。我认为它与 FileObjectQueue.Converter 有关。

我目前正在尝试使用来自我的子任务的讨厌的包装回调接口来解决这个问题。

我的要求是拥有一个 TapeQueue 并能够发送多种类型的任务。所以我有一个 TapeTask 抽象类,并有具体的实现,如 ImageDownloadTask、ImageUploadTask、UrlPostWithRetrofitTask、GoogleAnalyticsTrackerTask 等。所有这些都进入一个队列。

有没有办法做到这一点。我想我的问题归结为: 我需要做什么才能使 FileObjectQueue.Converter 与抽象类很好地配合

提示:P:该类的 javadoc 说“..您还需要在序列化字节数组中包含具体的类名”,但我不确定这意味着什么。如果有人可以解释如何将名称包含在序列化字节数组中,以达到我的目的,我将不胜感激!

4

1 回答 1

2

我继续写了一个抽象 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();
    }
}
于 2014-07-09T16:46:20.800 回答