Gson toJson(), weird behavior (produce empty json)
Asked Answered
S

1

6

I have problems serializing / deserializing this class with Gson:

public class Test {

    @SerializedName("id")
    private String mId;

    public String getId() { return mId; }

    public static Test fromJson(String json) { return new Gson().fromJson(json, Test.class); }
    public String toJson() { return new Gson().toJson(this, Test.class); }
}

If I run this:

Test test = Test.fromJson("{\"id\":\"1465988493\"}");
Log.i(TAG, "Test: " + test.toJson());
//Log.i(TAG, "Test id: " + test.getId());

It prints:

Test: {}

But if I run this:

Test test = Test.fromJson("{\"id\":\"1465988493\"}");
Log.i(TAG, "Test: " + test.toJson());
Log.i(TAG, "Test id: " + test.getId());

It works as expected and prints:

Test: {"id":"1465988493"}

Test id: 1465988493

So calling the getter AFTER calling toJson made toJson() to work. WTF???

Last thing, if I initialize the id to null:

public class Test {

    @SerializedName("id")
    private String mId = null; // <- Init to null

    public String getId() { return mId; }

    public static Test fromJson(String json) { return new Gson().fromJson(json, Test.class); }
    public String toJson() { return new Gson().toJson(this, Test.class); }
}

Then everything works as expected, and this code:

String testJson = "{\"id\":\"1465988493\"}";
Test test = Test.fromJson(testJson);
Log.i(TAG, "Test: " + test.toJson());
//Log.i(TAG, "Test id: " + test.getId());

Prints:

Test: {"id":"1465988493"}

So, I have the solution (initialize all my fields to null), but I'd like to understand what's wrong??

Smoky answered 16/6, 2016 at 14:9 Comment(4)
I can't reproduce this. Don't use single quotes for JSON strings (although Gson is able to parse them).Salahi
Any chances that you used proguard? without Log.i(TAG, "Test id: " + test.getId()); whole "id stuff" can be removed in optimalization as you are not using itAuld
Thanks. Same problem with double quotes (I use double quotes in the code, I changed to single while writing the post, to readability). Yes I'm using Proguard, why?Smoky
Saw your edit. OK thanks a lot, indeed proguard was the cause. Please post an answer, I'll accept it (and provide proguard configuration from the accepted answer of this post : #23826671).Smoky
H
5

There is just proguard problem. If you use proguard just keep in mind the proguard can remove some fields from class if you don't use it. For example your app doesn't use getters of class. So easy way just add annotation to keep it like:

@SerializedName("id")
@Keep
private String mId;

Or add keep rule to your proguard file.

Hoist answered 30/4, 2019 at 16:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.