Limitations of Realm
In the year since we launched Realm for Android, we have been honored by the popularity of our library despite its limitations. In particular, we have heard many complaints about the requirement to extend classes from RealmObject
, which in turns causes the following constraints:
- No public fields
- Only standard accessor names
- No added logic to accessors
- No custom methods
- No implementing of interfaces
All these limitations come from a common reason: Realm is using proxy classes to perform zero-copy operations on the underlying data store. Let us go through all the limitations one by one.
No public fields
Java does not allow proxies to access fields, so Realm proxy classes cannot intercept when such fields are accessed. Also, fields are by definition stored in the Java heap. This means that data would have to be copied from Realm to Java memory, which is against our zero-copy practice.
Only standard accessor names
Annotations processors are extremely powerful tools, but they have some limitations. One of those is the inability to inspect the actual code of the class being proxied: only fields and methods names are available. This means that we had to rely on convention to make Realm proxy classes behave as expected.
No added logic to accessors
This is a direct consequence of the previous limitation. Since the implementation of the accessors cannot be accessed by the annotation processor, it is impossible to replicate such logic in the proxy classes. Of course we could simply call super.getMyField();
, but that operates on the in-memory data, which is not being used in the proxy class.
No custom methods
Again, since the annotation processor cannot inspect code, it’s impossible to guess what a custom method actually does. Hence, Realm cannot allow such methods in order to guarantee correctness.
No implementing of interfaces
Since custom methods are not allowed, interfaces that require the implementation of methods are not allowed either.
So, How to Fix This?
The only way to overcome such limitations is with bytecode weaving. This means that after compilation is over, some modifications are applied to the .class
files. We will go through the details of such operation in a future blog post. What’s important here is that the only way to cleanly perform bytecode weaving on Gradle builds is with a plugin. This is also what the popular libraries RetroLambda and Hugo are doing, so we know we are in good company!
Your build.gradle file
Until now, you installed Realm like this:
repositories {
jcenter()
}
dependencies {
compile 'io.realm:realm-android:<version>'
}
With the Gradle plugin, it looks like this:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:<version>"
}
}
apply plugin: 'realm-android'
The first code sample should already be in your build.gradle
file, so all you need to add are the lines staring with classpath
and apply plugin: 'realm-android'
.
Why Now?
Why do we provide the plugin now, even before the bytecode weaving step is released? There are actually some other reasons!
Smaller APKs!
Using the plugin we can now ship Realm as an AAR, as opposed to a JAR. We can also avoid including the annotation processor in the library and make it a standalone package. This means the your final APKs will not have to include the annotation processor, shaving a few kilobytes off your app.
Easy ABI splits!
Another consequence of shipping an AAR is that now you are able to cleanly perform ABI splits without having to use the workaround described in our previous blog post. This means that you won’t have to ship a single APK containing native libraries for all CPU architectures.
What About Eclipse?
As you probably already know, Google is deprecating the ADT plugin for Eclipse and is ending its support at the end of the year. As far as we can tell, the vast majority of Android developers have already switched over to Android Studio, so that’s where we are focusing our efforts. That being said, our priorities are dictated by your feedback, and we will consider writing an Ant or Maven plugin if enough people ask for it.
Happy Coding!
We hope you will find this change useful! Please don’t hesitate to contact us. As always, we’re around on Stack Overflow, GitHub, and Twitter.
Receive news and updates from Realm straight to your inbox