Невозможно получить значения полей из объекта realm, значения равны нулю в отладчике

Кажется, что мои значения RealmObject скрыты classом RealmProxy, но могут быть установлены из proxyclass.

Моя модель довольно прямолинейна, как вы можете видеть.

public class GroupRealm extends RealmObject { @PrimaryKey public String id; @Index public String name; public String imageUrl; public int order; public GroupRealm parent; public RealmList children; public RealmList contents; } 

Вот как я устанавливаю значения (db – действительное Царство, и все в транзакции, которая совершает штраф):

 GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst(); if(gr==null){ gr = db.createObject(GroupRealm.class,g.GroupID); } gr.imageUrl = g.GlyphUrl; gr.name = g.Title; gr.order = g.OrderNum; 

Изображение ниже – это то, что я получаю, когда я запрашиваю последний db. (То же имя переменной не такое же место в коде)

RealmObject имеет значения RealmProxyClass не

В моей android.library, где мой проект RealmObjects определен, у меня есть необходимые плагины.

 apply plugin: 'com.android.library' apply plugin: 'realm-android' 

и на уровне проекта я устанавливаю правильные зависимости:

 dependencies { classpath 'com.android.tools.build:gradle:2.1.0' classpath "io.realm:realm-gradle-plugin:0.90.1" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } 

У меня нет идей. Если я попытаюсь получить доступ к чему-либо, я получаю GroupRealm, как ожидалось, но все публичные свойства, открытые через class прокси, возвращают null!

Соответствующие FAQ в документации: https://realm.io/docs/java/latest/#debugging


Realm использует Android Gradle Transform API. Это дает возможность манипулировать скомпилированными файлами classов, прежде чем они будут преобразованы в файлы dex.
Подробнее внутри io.realm.transformer.RealmTransformer и io.realm.transformer. Класс BytecodeModifier, который можно найти в github в области.

Что RealmTransformer делает, среди прочих:

  • заменяя все обращения к полям пользовательских RealmObjects с помощью соответствующих агентов доступа Realm.

Вы также можете проверить classы результатов внутри папки app / build / intermediates / transforms / RealmTransformer /

Пример настройки:
Строка вашего кода:

 gr.imageUrl = g.GlyphUrl; 

будет заменено чем-то вроде этого:

 String var5 = g.GlyphUrl; gr.realmSet$imageUrl(var5); 

Пример геттера:

 String url = gr.imageUrl; 

будет заменено чем-то вроде этого:

 String url = gr.realmGet$imageUrl(); 

Пример использования

  1. Вы создали class GroupRealm . Realm с использованием Transform API генерирует GroupRealmRealmProxy . Этот прокси-class выглядит следующим образом:

     public class GroupRealmRealmProxy extends GroupRealm implements RealmObjectProxy, GroupRealmRealmProxyInterface { private final GroupRealmRealmProxy.GroupRealmColumnInfo columnInfo; private final ProxyState proxyState; private RealmList childrenRealmList; private RealmList contentsRealmList; private static final List FIELD_NAMES; GroupRealmRealmProxy(ColumnInfo columnInfo) { ... } public String realmGet$id() { this.proxyState.getRealm$realm().checkIfValid(); return this.proxyState.getRow$realm().getString(this.columnInfo.idIndex); } public void realmSet$id(String value) { this.proxyState.getRealm$realm().checkIfValid(); if(value == null) { this.proxyState.getRow$realm().setNull(this.columnInfo.idIndex); } else { this.proxyState.getRow$realm().setString(this.columnInfo.idIndex, value); } } public String realmGet$name() { this.proxyState.getRealm$realm().checkIfValid(); return this.proxyState.getRow$realm().getString(this.columnInfo.nameIndex); } public void realmSet$name(String value) { this.proxyState.getRealm$realm().checkIfValid(); if(value == null) { this.proxyState.getRow$realm().setNull(this.columnInfo.nameIndex); } else { this.proxyState.getRow$realm().setString(this.columnInfo.nameIndex, value); } } ... } 

    Вы можете заметить, что методы realmSet $ ​​name и realmGet $ name не имеют доступа к имени поля, объявленному в classе GroupRealm. Они используют proxyState .

  2. Теперь вернемся к использованию GroupRealm. Когда вы отлаживаете свой код:

     GroupRealm gr = db.where(GroupRealm.class).equalTo("id",g.GroupID).findFirst(); if(gr==null){ gr = db.createObject(GroupRealm.class,g.GroupID); } gr.imageUrl = g.GlyphUrl; gr.name = g.Title; gr.order = g.OrderNum; 

    в действительности это декомпилированная версия выглядит следующим образом:

     GroupRealm gr = (GroupRealm)realm.where(GroupRealm.class).equalTo("id", g.GroupId).findFirst(); if(gr == null) { gr = (GroupRealm)realm.createObject(GroupRealm.class, g.GroupId); } String var7 = g.GlyphUrl; gr.realmSet$imageUrl(var7); var7 = g.Title; gr.realmSet$name(var7); int var8 = g.OrderNum; gr.realmSet$order(var8); 

    Прежде всего, gr является экземпляром classа GroupRealmRealmProxy . Как вы можете видеть, установка gr.name заменяется на gr.realmSet $ ​​name (var7) . Это означает, что имя поля GroupRealm никогда не используется. Ситуация аналогична ситуации в случае realmGet $ .

Во время отладки вы видите свою версию исходного кода, но на самом деле вы используете модифицированную версию с инъецированными методами realmSet $ и realmGet $ .

Поля нулевые. Вы получаете доступ к свойствам через собственный метод, который заменяет весь доступ к полю. Ранее (до 0.88.0) он использовался для создания динамического прокси-сервера, который заставлял ваши получатели и сеттеры использовать свою собственную реализацию прокси-сервера.

Поля не имеют значений. Но, как вы можете видеть, объект Realm имеет очень хорошие значения: он говорит об этом в значении toString ().

Ничего не поделаешь. Из-за «умной» вещи, которую делает Realm, отладчику полностью запрещено делать то, что он должен. Вам придется полагаться на множество операторов Log.d.

Прости. Это просто реальность.

  • RecyclerView прокручивал прослушиватель UP / DOWN
  • В чем разница между match_parent и fill_parent?
  • Двойная SIM-карта Android
  • Android-кнопка Onclick
  • Android - получить значение от HashMap
  • URLConnection или HTTPClient: что обеспечивает лучшую функциональность и эффективность?
  • Как сделать копию файла в андроиде?
  • Как увеличить размер кучи приложения для Android?
  • Как поддерживать несколько версий Android в коде?
  • RecyclerView внутри DrawerLayout в LinearLayout, не прокручиваемый / кликабельный
  • Как нарисовать линию в android
  • Давайте будем гением компьютера.