无法从领域对象中检索字段值,debugging器中的值为空

看起来像我的RealmObject值被RealmProxy类隐藏,但可以从代理类设置。

你可以看到,我的模型非常简单。

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

这是我如何设置值(数据库是一个有效的领域,并且一切都在提交的事务中):

 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; 

下面的图片是当我查询数据库后,我得到的(相同的variables名称不同于代码中的地方)

RealmObject的值不是RealmProxyClass

在我的RealmObjects被定义的项目我的android.library我有必要的插件。

 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,但通过代理类公开的所有属性均返回null!

文档中的相关FAQ: https : //realm.io/docs/java/latest/#debugging


Realm使用Android Gradle Transform API。 它可以在编译的类文件转换为dex文件之前对其进行操作。
io.realm.transformer.RealmTransformerio.realm.transformer中的更多细节 BytecodeModifier类可以在领域的github中find。

RealmTransformer所做的是:

  • 用适当的Realm访问器replace对用户的RealmObjects的字段的所有访问。

你也可以检查文件夹app / build / intermediates / transforms / RealmTransformer /

setter的例子:
你的代码行:

 gr.imageUrl = g.GlyphUrl; 

将被replace为这样的东西:

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

获得者的例子:

 String url = gr.imageUrl; 

将被replace为这样的东西:

 String url = gr.realmGet$imageUrl(); 

示例用例

  1. 你已经创build了GroupRealm类。 使用Transform API的领域生成GroupRealmRealmProxy 。 这个代理类看起来像这样:

     public class GroupRealmRealmProxy extends GroupRealm implements RealmObjectProxy, GroupRealmRealmProxyInterface { private final GroupRealmRealmProxy.GroupRealmColumnInfo columnInfo; private final ProxyState proxyState; private RealmList<GroupRealm> childrenRealmList; private RealmList<ContentRealm> contentsRealmList; private static final List<String> 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 $ namerealmGet $ name方法不能访问类GroupRealm中声明的字段名称 。 他们使用proxyState

  2. 现在,让我们回到GroupRealm的使用。 当你debugging你的代码时:

     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); 

    首先, grGroupRealmRealmProxy类的实例。 正如你所看到的,gr.name的设置被gr.realmSet $ name(var7)所取代。 这意味着GroupRealm的字段名称从不使用。 这种情况在realmGet $的情况下是类似的。

在debugging的时候,你会看到你的源代码版本,但是实际上你使用了一个修改后的版本,注入方法是realmSet $realmGet $

这些字段空的。 您可以通过replace所有字段访问的本地方法访问属性。 以前(在0.88.0之前),它用来创build一个dynamic代理,覆盖你的getter和setter来使用他们的本地代理实现。

这些字段没有值。 但是,正如你所看到的,Realm对象的值很好:它在toString()值中是这样表示的。