I have a POJO in Android, which is serialized from a server's JSON response with GSON, without any problem.
public ExampleClass implements Serializable {
@Expose
String someProperty;
}
For some reason, I would like to store a Handler object in my class, like:
public ExampleClass implements Serializable {
private Handler handler = new Handler();
@Expose
String someProperty;
}
After adding this extra line, the serialization breaks with
java.lang.RuntimeException: Failed to invoke public com.example.android.ExampleClass() with no args
I've tried adding a no-args constructor for my class, no success. I've tried making the Handler object transient, but still no success.
UPDATE:
So, I've found the solution. The problem here is that the Handler object is initialized before finishing the serialization of the object.
So this isn't breaking the serialization:
public ExampleClass implements Serializable {
private Handler handler;
@Expose
String someProperty;
}
But where to initialize it? If I try to do it in the no-args constructor, the serialization breaks again:
public ExampleClass implements Serializable {
private Handler handler;
@Expose
String someProperty;
public ExampleClass() {
handler = new Handler(); // breaks serialization
}
}
If I initialize it later when the serialization finished, it works:
public ExampleClass implements Serializable {
private Handler handler;
@Expose
String someProperty;
public void functionCalledInTheFuture() {
handler = new Handler(); // works
}
}
I am not completely understanding this, so if somebody can explain it to me, please don't hesitate! :)
Well... this is interesting because transient
keyword should do the trick. But.. this is only a shortcut to a common use-case. It may not work if the library or code that handle the serialization process ignores it.
There is a good article, that covers serialization topic in JAVA ( read this ). In short : you may customize ExclusionStrategy
to add a dedicated behavior to your class
Code highlights:
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);
Yes.. this is probably an overkill to your problem, but it should work for all use cases
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.