Преобразование объекта в строку Json и обратное преобразование в объект с отсутствующим элементом DateTime Android - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь сохранить объект в общих настройках и затем извлечь.

Объект состоит из одного DateTime для текущего дня и списка объектов для крупнейших проигравших акций ( акции символовв виде строки, а процентное изменение в виде двойного ).

Модель объекта:

public class DayLosersSharedPreference {

    LocalDateTime dateTime;
    List<PercentageChange> percentageChangesList;

    public LocalDateTime getDateTime() {
        return dateTime;
    }

    public void setDateTime(LocalDateTime dateTime) {
        this.dateTime = dateTime;
    }

    public List<PercentageChange> getPercentageChangesList() {
        return percentageChangesList;
    }

    public void setPercentageChangesList(List<PercentageChange> percentageChangesList) {
        this.percentageChangesList = percentageChangesList;
    }
}

Одиночный объект (содержащий DateTime и список объектов) передается в мой класс общих настроек для хранения следующим образом:

public class SharedPreferences {

    Context context = MySuperAppApplication.getContext();
    android.content.SharedPreferences sharedPreferences = context.getSharedPreferences(STRINGS.LOSERS_SP(), Context.MODE_PRIVATE);
    Gson gson = new Gson();

    public void storeLosers(DayLosersSharedPreference losers) {

        System.out.println("Object being stored date: " + losers.getDateTime());
        System.out.println("Object being stored array: " + losers.getPercentageChangesList());

        String dailyLosersJson = gson.toJson(losers);

        System.out.println("Object being stored as Json String: " + dailyLosersJson);

        sharedPreferences.edit()
                .putString(STRINGS.DAILY_LOSERS_SP(), dailyLosersJson)
                .apply();
    }
}

Вывод функции println () показывает объект до преобразования Json String в порядке:

I/System.out: Object being stored date: 2019-03-18T00:00
I/System.out: Object being stored array: [com.roboticc.alpha.Models.PercentageChange@8bef7ab, com.roboticc.alpha.Models.PercentageChange@207be08, com.roboticc.alpha.Models.PercentageChange@b6289a1, com.roboticc.alpha.Models.PercentageChange@269d7c6, com.roboticc.alpha.Models.PercentageChange@ff36387, com.roboticc.alpha.Models.PercentageChange@45eb2b4, com.roboticc.alpha.Models.PercentageChange@1fd1edd, com.roboticc.alpha.Models.PercentageChange@41baa52, com.roboticc.alpha.Models.PercentageChange@b18b123, com.roboticc.alpha.Models.PercentageChange@38e4620]

Но есть проблема в том, как я преобразовываю это в строку Json.Когда я смотрю на вывод после того, как он был преобразован, он теряет элемент DateTime:

I/System.out: Object being stored as Json String: {"dateTime":{},"percentageChangesList":[{"percentageChange":-0.15908367801463796,"symbol":"AAL"},{"percentageChange":0.0,"symbol":"AAME"},{"percentageChange":0.19011406844106543,"symbol":"AABA"},{"percentageChange":0.500000000000002,"symbol":"AAOI"},{"percentageChange":0.6455517450070613,"symbol":"AAWW"},{"percentageChange":0.8957770510450668,"symbol":"AAXJ"},{"percentageChange":1.0208467655276197,"symbol":"AAPL"},{"percentageChange":1.081223628691974,"symbol":"ABCB"},{"percentageChange":2.0748867159551576,"symbol":"AAON"},{"percentageChange":4.29524603836531,"symbol":"AAXN"}]}

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

Я предполагаю, что что-то не так с тем, как я преобразовываю объект в строку Json. Должен ли я что-то делать, например, передавать тип модели?или DateTime не может быть сохранен в Json в этом формате?

Спасибо за вашу помощь

РЕДАКТИРОВАТЬ: мне удалось изменить DateTime на строку и преобразовать обратно после поиска, чтобы исправить это.Мне все еще интересно, почему это не работает напрямую без преобразования DateTime.Особенно учитывая, что весь список объектов может быть передан.

1 Ответ

1 голос
/ 19 марта 2019

gson не знает об объектах LocalDateTime и, следовательно, не может его проанализировать. Если вы хотите, чтобы он непосредственно анализировал LocalDateTime без необходимости сначала преобразовывать его в строку, вы должны указать gson, КАК анализировать LocalDateTime с помощью registerTypeAdaptor.

Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
    @Override
    public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        Instant instant = Instant.ofEpochMilli(json.getAsJsonPrimitive().getAsLong());
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
}).create();

Это то, что новые версии GSON могут обрабатывать, хотя: https://github.com/google/gson/pull/1266/files

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

...