Google gson Класс LinkedTreeMap, добавленный в myclass

Я знал, что этот вопрос был задан раньше. Из-за моего новичка в java и android. Я не могу решить эту проблему больше недели.

Один из моих друзей и я, разрабатывающий проект андроида, были такие вещи, как это.

Самая странная часть этой вещи - это происходит только с момента загрузки и тестирования ее из магазина Google Play. Не из локальной установки установки или отладки в студии Android.

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

Пожалуйста, предложите мне, где я должен продолжать копать?

@Override
public void promiseMethod(JSONObject object) {
    if (object != null) {

        if (object.has(DO_SERVICES)) {
            vehicleDetails = new ArrayList < Object[] > (1);
            List < String > vehicleNoList = new ArrayList < String > (1);
            List < String > serviceList = new ArrayList < String > (1);
            try {
                Gson gson = new Gson();
                JSONObject jsonObj = new JSONObject(object.get(DO_SERVICES)
                    .toString());
                servDto = gson.fromJson(jsonObj.toString(),
                    ServiceDto.class);


                if (servDto.getServiceDto() instanceof List) {

                    List < DoServiceDto > doServiceList = servDto.getServiceDto();

Исключение составляет

java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap не может быть добавлено в com.gaurage.dto.DoServiceDto   at com.gaurage.user.User_Test_Main.promiseMethod(Неизвестный источник)

Ответ 1

Сериализация и десериализация общих типов

Когда вы вызываете toJson (obj), Gson вызывает obj.getClass(), чтобы получить информацию о полях для сериализации. Аналогично, вы можете передать объект MyClass.class в методе fromJson (json, MyClass.class). Это отлично работает, если объект является не общим типом. Однако, если объект имеет общий тип, информация типа Generic теряется из-за Java Type Erasure. Вот пример, иллюстрирующий точку:

class Foo<T> {  T value;}
Gson gson = new Gson();
Foo<Bar> foo = new Foo<Bar>();
gson.toJson(foo); // May not serialize foo.value correctly
gson.fromJson(json, foo.getClass()); // Fails to deserialize foo.value as Bar

Вышеприведенный код не интерпретирует значение как тип Bar, потому что Gson вызывает list.getClass(), чтобы получить его информацию о классе, но этот метод возвращает исходный класс Foo.class. Это означает, что Gson не знает, что это объект типа Foo, а не просто Foo.

Вы можете решить эту проблему, указав правильный параметризованный тип для своего общего типа. Вы можете сделать это, используя класс TypeToken.

Type fooType = new TypeToken<Foo<Bar>>() {}.getType();    
gson.toJson(foo, fooType);
gson.fromJson(json, fooType);

У меня есть класс родителя, и он является дочерним классом, некоторые из которых имеют в нем типы списков. Как и этот родительский класс, у меня есть 30 файлов. Я решил это так.

Gson gson = new Gson();
JSONObject jsonObj = new JSONObject(object.get(DO_SERVICES).toString());
Type type = new TypeToken<MyDto>() {}.getType();
servDto = gson.fromJson(jsonObj.toString(),type);

Самое главное, я не могу воспроизвести эту ошибку в локальном тестировании из студии Android. Эта проблема возникает только тогда, когда я генерирую подписанное приложение apk и публиковать в PlayStore, были прекращены приложения, и в отчете говорится: "Нельзя использовать LinkedTreeMap для myclass.

Мне было трудно воспроизвести тот же результат в моем локальном тестировании (включая режим Debug).

Ответ 2

Источник

В моем ListView BaseAdapter сталкиваются с той же проблемой

JSON формат для отображения

{
    results: [
    {
        id: "10",
        phone: "+91783XXXX345",
        name: "Mr Example",
        email: "[email protected]"
    },
    {
        id: "11",
        phone: "+9178XXXX66",
        name: "Mr Foo",
        email: "[email protected]"
    }],
    statusCode: "1",
    count: "2"
}

Я столкнулся с этой проблемой

E/AndroidRuntime: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.hsa.ffgp.hapdfgdfgoon, PID: 25879 java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap не может быть приведен к com.hsa.......

Затем я сопоставил данные, используя значение ключа LinkedTreeMap, как показано ниже

...
...

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {
        if(view==null)
        {
            view= LayoutInflater.from(c).inflate(R.layout.listview_manage_clients,viewGroup,false);
        }

        TextView mUserName = (TextView) view.findViewById(R.id.userName);
        TextView mUserPhone = (TextView) view.findViewById(R.id.userPhone);


        Object getrow = this.users.get(i);
        LinkedTreeMap<Object,Object> t = (LinkedTreeMap) getrow;
        String name = t.get("name").toString();

        mUserName.setText("Name is "+name);
        mUserPhone.setText("Phone is "+phone);

        return view;
    }
...
...

Ответ 3

В моем случае произошла ошибка при получении списка объектов из общих настроек. Ошибка была решена путем добавления TypeToken, как показано ниже:

 public static <GenericClass> GenericClass getListOfObjectsFromSharedPref(Context context,String preferenceFileName, String preferenceKey ){

    SharedPreferences sharedPreferences = 
    context.getSharedPreferences(preferenceFileName, 0);
    Type type = new TypeToken<ArrayList<Classname.class>>() {}.getType();
    String json = sharedPreferences.getString(preferenceKey, "");
    final Gson gson = new Gson();
    return gson.fromJson(json, type);
}

....