我已经开始在我的应用程序中使用Realm数据库但是我无法理解Realm如何知道我的模型类的成员。
我的领域模型类唯一的注释是@PrimaryKey
只有一个变量,其他变量没有注释。
我能想到的另一种方式是Realm使用反射来计算模型类中的变量,但由于Android上的反射很慢,我认为Realm不依赖于反射,因为它们将自己推销为快速数据库。 / p>
有人可以告诉我领域是如何运作的,或者可以指向一些显示领域如何运作的文章?
答案 0 :(得分:0)
Realm使用注释处理。
注释处理是一种允许您在编译时执行相当强大功能的技术。它可以访问您的所有课程并检查您的所有属性和方法。
我认为Realm也会使用AST(抽象语法树)修改来代理get / set方法。这是一种更先进(但功能更强大)的技术
您可以在this tutorial
中找到有关注释处理的更多信息此外,如果您想检查注释处理和AST修改的另一个示例,您可以查看this repo。这是我前段时间制作的一个项目
答案 1 :(得分:0)
我的领域模型类唯一的注释是@PrimaryKey只有一个变量,其他变量没有注释。
错误:)当你说extends RealmObject
时,你实际上是从一个定义为
@RealmClass // <---- annotation
public abstract class RealmObject implements RealmModel {
}
因此,您的类具有注释处理器注册的@RealmClass
注释,然后它可以读取所有字段,如:
@AutoService(Processor.class)
public class ExampleProcessor extends AbstractProcessor {
ProcessingEnvironment processingEnvironment;
Elements elements;
Messager messager;
Filer filer;
Types types;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.processingEnvironment = processingEnv;
this.filer = processingEnvironment.getFiler();
this.elements = processingEnvironment.getElementUtils();
this.messager = processingEnvironment.getMessager();
this.types = processingEnvironment.getTypeUtils();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(RealmClass.class);
for(Element element : annotatedElements) {
// ...
}
// ...
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
Set<String> annotations = new HashSet<>();
annotations.add(RealmClass.class.getName());
return Collections.unmodifiableSet(annotations);
}
}
然后,它可以为使用@RealmClass
注释的每个对象生成代理类。该代码在here开源时可用。
当您拥有包含RealmObjects的库项目时,它会变得有点棘手,因此您需要指定@RealmModule
(以定义架构并且它是库模块)。
至于用代理getter / setter替换字段访问,这是由一个名为Realm-Transformer
的Gradle插件(使用Javassist)完成的,它使用所谓的 Transform API ,并且是用Groovy编写的。