android - No se pueden recuperar los valores de campo del objeto de reino, los valores son nulos en el depurador
realm (3)
Los campos son nulos. Accede a las propiedades a través de un método nativo que reemplaza todo acceso de campo. Anteriormente (antes de 0.88.0) solía crear un proxy dinámico que anulaba sus captadores y establecedores para usar su implementación de proxy nativo.
Los campos no tienen valores. Pero como puede ver, el objeto Realm tiene los valores bien: lo dice en el valor toString ().
Parece que mis valores RealmObject están ocultos por la clase RealmProxy, pero se pueden establecer desde la clase proxy.
Mi modelo es bastante sencillo como puedes ver.
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;
}
Así es como estoy configurando los valores (db es un Reino válido, y todo está en una transacción que se compromete bien):
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;
La imagen a continuación es lo que obtengo cuando consulto el último DB. (Mismo nombre de variable, no el mismo lugar en el código)
En mi android.library donde mis proyectos RealmObjects están definidos, tengo los complementos necesarios.
apply plugin: ''com.android.library''
apply plugin: ''realm-android''
y en el nivel del proyecto estoy estableciendo las dependencias correctas:
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
}
Se me acabaron las ideas. Si intento acceder a algo, recupero GroupRealm como se esperaba, pero todas las propiedades públicas expuestas a través de la clase proxy devuelven nulo.
No hay nada que hacer al respecto. Debido a lo "inteligente" que Realm está haciendo, el depurador no puede hacer lo que se supone que debe hacer. Tendrá que confiar en muchas declaraciones Log.d.
Lo siento. Esa es solo la realidad.
Preguntas frecuentes relevantes en la documentación: realm.io/docs/java/latest/#debugging
Realm usa la API de Android Gradle Transform.
Da la posibilidad de manipular archivos de clase compilados antes de que se conviertan en archivos dex.
Más detalles dentro de
io.realm.transformer.RealmTransformer
y
io.realm.transformer.
Clases de
BytecodeModifier
que se pueden encontrar en el github del reino.
Lo que hace RealmTransformer, entre otros, es:
- reemplazando todos los accesos a los campos de RealmObjects del usuario con los accesos de Realm apropiados.
También puede verificar las clases de resultados dentro de la carpeta app / build / intermediates / transforms / RealmTransformer /
Ejemplo de setter:
Línea de su código:
gr.imageUrl = g.GlyphUrl;
será reemplazado por algo como esto:
String var5 = g.GlyphUrl;
gr.realmSet$imageUrl(var5);
Ejemplo de getter:
String url = gr.imageUrl;
será reemplazado por algo como esto:
String url = gr.realmGet$imageUrl();
Ejemplo de caso de uso
-
Has creado la clase GroupRealm . El dominio que usa Transform API genera GroupRealmRealmProxy . Esta clase de proxy se ve así:
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); } } ... }
Puede observar que los métodos realmSet $ name y realmGet $ name no tienen acceso al nombre de campo declarado en la clase GroupRealm. Usan proxyState .
-
Ahora, volvamos al uso de GroupRealm. Cuando depure su código:
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;
en realidad su versión descompilada se ve así:
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);
En primer lugar, gr es la instancia de la clase GroupRealmRealmProxy . Como puede ver, la configuración de gr.name se reemplaza por gr.realmSet $ name (var7) . Significa que el nombre de campo de GroupRealm nunca se usa. La situación es análoga en el caso de realmGet $ .
Mientras realiza la depuración, ve su versión del código fuente, pero en realidad está utilizando una versión modificada con métodos inyectados realmSet $ y realmGet $ .