似乎RealmProxy类隐藏了我的RealmObject值,但可以从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<GroupRealm> children;
    public RealmList<ContentRealm> contents;
}

这就是我设置值的方式(db是有效的Realm,并且一切都在提交正常的事务中):
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时得到的结果(相同的变量名称在代码中的位置不同)

android - 无法从 Realm 对象检索字段值,调试器中的值为null-LMLPHP

在我的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,但是通过代理类公开的所有公共(public)属性都将返回null!

最佳答案

文档中的相关常见问题解答:https://realm.io/docs/java/latest/#debugging

Realm使用Android Gradle Transform API。它提供了在将已编译的类文件转换为dex文件之前对其进行处理的可能性。
io.realm.transformer.RealmTransformer io.realm.transformer中的更多详细信息。可以在 Realm 的github中找到的BytecodeModifier 类。

除其他外,RealmTransformer的作用是:

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

  • 您还可以在 app/build/intermediates/transforms/RealmTransformer/文件夹中检查结果类

    setter的示例:
    您的代码行:
    gr.imageUrl = g.GlyphUrl;
    

    将被替换为以下内容:
    String var5 = g.GlyphUrl;
    gr.realmSet$imageUrl(var5);
    

    setter/getter 示例:
    String url = gr.imageUrl;
    

    将被替换为以下内容:
    String url = gr.realmGet$imageUrl();
    

    用例示例
  • 您已经创建了类GroupRealm 类。使用Transform API的 Realm 生成 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 $ name realmGet $ name 无法访问在GroupRealm类中声明的名称字段。他们使用 proxyState
  • 现在,让我们回到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 GroupRealmRealmProxy 类的实例。如您所见,gr.name的设置已替换为 gr.realmSet $ name(var7)。这意味着从不使用 GroupRealm 的字段名称。在 realmGet $ 的情况下,情况类似。

  • 在调试时,您会看到源代码的版本,但实际上您使用的是经过修改的版本,其中注入(inject)了 realmSet $ realmGet $

    关于android - 无法从 Realm 对象检索字段值,调试器中的值为null,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37351703/

    10-10 17:59