0

In my app I use gson to save a list of custom objects List<AppBasicView> appViews. The objects are instances of AppBasicView (AppBasicView objects and child objects of that class). The AppBasicView class is built like that:

public class AppBasicView {
    enum BasicViewType {ImageView}

    private BasicViewType mBasicViewType;
    private LinearLayout.LayoutParams mLayoutParams;

    public AppBasicView(BasicViewType basicViewType, LinearLayout.LayoutParams layoutParams) {
        this.mBasicViewType = basicViewType;
        this.mLayoutParams = layoutParams;
    }
    ...
    (getters&setters)
}

AppTextView - the child class of AppBasicView, is built like that:

public class AppTextView extends AppBasicView {
    enum TextViewType {Button, TextView, EditText}

    private TextViewType mTextViewType;
    private String mText;

    public AppTextView(TextViewType textViewType, LinearLayout.LayoutParams layoutParams, String mText) {
        super(null, layoutParams);
        this.mTextViewType = textViewType;
        this.mText = mText;
    }
    ...
    (getters&setters)
}

I'm saving the list like that:

Gson gson = new Gson();
String json = gson.toJson(appViews);
spEditor.putString("app1objects", json);
spEditor.apply();

Problem 1

The json string I get when saving AppBasicView object contains only the mBasicViewType field (and doesn't contain mLayoutParams field).

And when I save AppBasicView child, the json string contains only child's additional fields and doesn't contain any of the parents (AppBasicView) fields (neither mBasicViewType nor mLayoutParams).

Can't understand why I'm not getting those fields serialized.

Problem 2

After deserialization I get the objects list with only AppBasicView views (even if they where AppTextView) that are not recognized as child objects of AppBasicView (for an AppBasicView v that was AppTextView, v instanceof AppTextView returns false).

This is the deserialization code:

String json = appDataPreferences.getString("app1objects", "");
Type listType = new TypeToken<ArrayList<AppBasicView>>(){}.getType();

if(!json.equals("null"))
    appViews = new Gson().fromJson(json, listType);

How can I get the full children object and use them as they were and not as up-casted objects?

Thanks for any help in advance!


  • This is how I add objects to the list (in case it could help to find the answer):
AppBasicView appBasicView;

if(...)
{
    appBasicView = new AppTextView(...);
}
else if(...)
{
    appBasicView = new AppBasicView(...);
}
else
    throw new CustomExceptions.InvalidDroppingViewTag();

...
appViews.add(appBasicView);
...

Solution 1

Disappeared fields turned out to be all null so gson didn't mention them because:

While serializing, a null field is omitted from the output.

To still see those fields you need to create your Gson like that: Gson gson = new GsonBuilder().serializeNulls().create();

Babushka
  • 3
  • 3
  • Could you please also include the source code for your "AppBasicView child"? It might be necessary to debug your app to find out the value of `mLayoutParams`. Maybe it is an instance of an anonymous or local class which Gson is unfortunately silently serializing as JSON null, see also https://github.com/google/gson/issues/1510 – Marcono1234 Oct 08 '22 at 16:00
  • Thanks. Your `AppTextView` constructor calls `super(layoutParams)`, but the superclass only has a constructor with two parameters. Could you please check if the code you provided here is correct? Could you please for debugging create the `Gson` instance like this: `Gson gson = new GsonBuilder().serializeNulls().create();`. If the missing fields appear then, but have the value `null` it at least shows that Gson does recognize the fields. I think the best approach would really to debug through the Gson calls to find out why it is not serializing the values of those fields. – Marcono1234 Oct 09 '22 at 19:47
  • Oh right, I forgot to add the second constructor of `AppBasicView`, gonna add now. Changed `Gson` creation, and yes! The fields appeared with the value of null. Changing the code in the question. However, there is still a problem. After desterilizing the objects list they all appear to be `AppBasicView` objects (even if they where `AppTextView` objects). Attaching the deserialization code. @Marcono1234 – Babushka Oct 10 '22 at 15:48
  • My bad, there is only one constructor, fixed the code in question. – Babushka Oct 10 '22 at 16:16
  • For the second problem, maybe https://stackoverflow.com/q/15736654 or similar questions help. Also, instead of including "Solution 1" in your question, you can also post an answer to your question yourself (and edit it later when you find the solution for your other problem as well). – Marcono1234 Oct 10 '22 at 18:55

0 Answers0