Сериализация объектов GSON прерывается, когда я добавляю объект Handler в свой класс модели - PullRequest
0 голосов
/ 27 октября 2018

У меня есть POJO в Android, который без каких-либо проблем сериализуется из ответа JSON сервера с GSON.

public ExampleClass implements Serializable {
    @Expose 
    String someProperty;
}

По какой-то причине я хотел бы сохранить объект Handler в своем классе, например:

public ExampleClass implements Serializable {

    private Handler handler = new Handler();

    @Expose 
    String someProperty;
}

После добавления этой дополнительной строки сериализация разрывается с

java.lang.RuntimeException: Failed to invoke public com.example.android.ExampleClass() with no args

Я пытался добавить конструктор без аргументов для моего класса, но безуспешно.Я пытался сделать объект Handler временным, но все равно безуспешно.


ОБНОВЛЕНИЕ:

Итак, я нашел решение.Проблема здесь заключается в том, что объект Handler инициализируется до завершения сериализации объекта.

Так что это не нарушает сериализацию:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;
}

Но где его инициализировать?Если я попытаюсь сделать это в конструкторе no-args, сериализация снова прекратится:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;

    public ExampleClass() {
        handler = new Handler(); // breaks serialization 
    }
}

Если я инициализирую его позже, когда закончится сериализация, он будет работать:

public ExampleClass implements Serializable {

    private Handler handler;

    @Expose 
    String someProperty;

    public void functionCalledInTheFuture() {
        handler = new Handler(); // works
    }
}

IЯ не совсем понимаю, поэтому, если кто-то может мне это объяснить, пожалуйста, не стесняйтесь!:)

1 Ответ

0 голосов
/ 27 октября 2018

Ну ... это интересно, потому что ключевое слово transient должно помочь. Но .. это всего лишь краткий путь к общему варианту использования. Он может не работать, если библиотека или код, которые обрабатывают процесс сериализации, игнорируют его.

Есть хорошая статья, посвященная теме сериализации в JAVA ( Прочтите это ). Короче говоря : вы можете настроить ExclusionStrategy, чтобы добавить отдельное поведение в ваш класс

Основные моменты кода:

ExclusionStrategy strategy = new ExclusionStrategy() {
    @Override
    public boolean shouldSkipField(FieldAttributes field) {
        if (field.getDeclaringClass() == MyClass.class && field.getName().equals("other")) {
            return true;
        }
        if (field.getDeclaringClass() == MySubClass.class && field.getName().equals("otherVerboseInfo")) {
            return true;
        }
        return false;
    }

    @Override
    public boolean shouldSkipClass(Class<?> clazz) {
        return false;
    }
};

Gson gson = new GsonBuilder()
  .addSerializationExclusionStrategy(strategy)
  .create();
String jsonString = gson.toJson(source);

assertEquals(expectedResult, jsonString);

Да .. это, вероятно, излишнее решение вашей проблемы, но оно должно работать для всех случаев использования

...