

Show HN: Realm for Android - timanglade
http://realm.io/news/realm-for-android/

======
jc4p
Just as a heads up your documentation doesn't work with the newest version of
the Android Gradle plugin (0.13.0), see here:
[http://stackoverflow.com/a/25939518/472021](http://stackoverflow.com/a/25939518/472021)

the `android-apt` dependency needs to be switched to 1.4 else you get:

    
    
        A problem occurred configuring project ':cachetest'.
        > No such property: projectDependencies for class: com.android.build.gradle.internal.api.ApplicationVariantImpl_Decorated
    

Edit #1: Is there any way to instantiate my RealmObject from JSON? I'm
currently using GSON to take API calls <\--> POJOs, I can't figure out any way
to do this using Realm since models "must be instantiated from the Realm using
the realm.createObject() instance method".

Edit #2: Okay I have no idea how to use this. Given a list of `Object`, how do
I make a `RealmList` of it? Do I have to use Realm.createObject? Is there not
any way of just taking a couple already instantiated versions of an object and
jamming them into a `RealmList`?

I was really excited about trying this out (the Stack Exchange app currently
has a 37ms delay on a cold start to get the list of all of our sites back into
active memory) but this does not look like it's going to be easy to use.

~~~
timanglade
Thanks for the heads-up! We’ll get that fixed shortly.

We do support JSON (and GSON) — you can see it at work in our gridViewExample
([https://github.com/realm/realm-
java/tree/master/examples/gri...](https://github.com/realm/realm-
java/tree/master/examples/gridViewExample))

~~~
jc4p
Eek so I actually have to make/use a setter for every single attribute of my
models? That's definitely a deal breaker for me.

~~~
tburch
try using [http://projectlombok.org/](http://projectlombok.org/)

~~~
greyskull
That's neat. I'll have to keep that in mind for the future.

I wish Java would take a hint from C# properties through :(

------
Groxx
Given the insert speeds, I'm guessing they're (still) not reusing compiled
statements. I mentioned this last time I saw Realm on the front page[1], but
their benchmarks are misleading without at least mentioning that they're doing
this.

I'm still very much interested in Realm, and LOVE having a competitor to
SQLite. But don't mislead your customers.

[1]:
[https://news.ycombinator.com/item?id=8043332](https://news.ycombinator.com/item?id=8043332)
where seepel finds SQLite to be more than twice as fast as Realm after that
one change to the benchmark.

~~~
timanglade
With those numbers that's an understandable assumption on your part, but as it
turns out the dev team did learn its lesson from your helpful pointers around
the time we launched for iOS…

I just checked our Android code and we __are __reusing compiled statements in
our benchmarks (Inserts only since compiled statements are not available for
multi-column queries, afawk). Here’s the code we use for inserts:

    
    
        public void testBatchInserts() throws PerformanceTestException {
            SQLiteStatement stmt = db.compileStatement("INSERT INTO "
                    + EmployeeDatabaseHelper.TABLE_EMPLOYEES + " VALUES(?1, ?2, ?3, ?4)");
    
            db.beginTransaction();
            for (int row = 0; row < getNumInserts(); row++) {
                stmt.clearBindings();
                stmt.bindString(2, getEmployeeName(row));
                stmt.bindLong(3, getEmployeeAge(row));
                stmt.bindLong(4, getEmployeeHiredStatus(row));
                stmt.executeInsert();
            }
            db.setTransactionSuccessful();
            db.endTransaction();
        }
    

So there you go: no intention to mislead. Us overlooking prepared statements
when we originally benched iOS was definitely a regrettable error but we do
try to improve. Thanks for helping us along the way.

~~~
Groxx
Glad to hear it! Guess it's more surprises between platforms :| Given that,
I'm even more interested in the Android version, and definitely curious what
the source code looks like - that's a respectable speedup, you must be doing
something right.

Would you have the source code for the benchmarks available somewhere? On the
iOS post there was a link, but I didn't see it on the android one.

~~~
timanglade
Yup we’re cleaning up the project right now and will post a link soon. It was
in the pile of things we didn’t quite get to do before launch… Sorry about the
delay.

I haven’t looked too deep personally but I don’t think the speedup comes from
anything new we’re doing in the C++ layer. It’s more likely coming from the
fact that we tried to find smart ways around Java & the JVM to avoid the kind
of copying or hijacking other ORMs do. We did hit some of that stuff again
yesterday/today as we just added migrations into the mix but we have some
theories on how to get some of that speed back.

------
lnanek2
Honestly, SQLite has a lot of utilities, tutorials, useful adapters and UI
hooks in Android. Core Data similarly on iOS. If you want me to go to your
framework instead, you'd have to provide something better than just redoing
the API. E.g. network sync like Couch does.

~~~
timanglade
Absolutely. SQLite definitely beats us today on documentation, ecosystem —
heck even on stability. Beyond offering a more simple API, we hope to have an
edge on performance, data size (~50% smaller on disk) and ease of use for
multi-threaded scenarios. As stated before, we’re also working on sync.
Eventually we do hope to catch up to (or do better than) SQLite & Core data on
docs & ecosystem as well. We all have to start somewhere, though!

------
zackb
I've always wondered how folks handle the Parcelable[1] interface with
libraries like this. If you have a realm object that you want to have in
memory between activity destroy/create how do you handle this? For instance if
I rotate the screen the activity is destroyed and recreated for the new
orientation. As I understand it the Parcelable interface and Bundle[2] is the
way to handle this but how can you do this if you're using third party
classes/objects?

Thanks!

[1]:
[http://developer.android.com/reference/android/os/Parcelable...](http://developer.android.com/reference/android/os/Parcelable.html)
[2]: [http://developer.android.com/training/basics/activity-
lifecy...](http://developer.android.com/training/basics/activity-
lifecycle/recreating.html)

~~~
makeramen
I use Parceler
([https://github.com/johncarl81/parceler](https://github.com/johncarl81/parceler))
with gson. So gson for network data, then parceler for passing parcels around
between activities/fragments.

~~~
zackb
Doesn't this require annotating the class? What if I can't change the class
implementation?

~~~
johncarl81
One way to use Parceler is to annotate the class. There are a lot of other
options though, including configuring the class outside of the class using
@ParcelClass (useful for libraries) or writing a ParcelConverter.

------
hayksaakian
If the main selling point is a nice interface, its not much of an improvemrnt
over things like ActiveAndroid (ORM for sqlite)

I'll need to read more to judge it on other grounds.

~~~
timanglade
Absolutely agreed! There’s some great APIs out there already if you use an
ORM. We try to offer an API that is simple (including across threads), while
offering performance that’s better than using raw SQLite.

------
jchrisa
It's good to see more options for mobile data. If you're interested in an open
source database that handles the network for you, Couchbase Lite syncs using
an Apache CouchDB compatible protocol:
[http://developer.couchbase.com/mobile/](http://developer.couchbase.com/mobile/)

------
pm
I'm using Realm on iOS at the moment for a reasonably large application. I
originally had a C cross-platform core based on SQLite, but I found it too
difficult to maintain and threw most of it out after attempting to make what
should've been a minor change that ended up going on for two weeks.

Realm reduced the core size by approximately 90%, and while I've given up the
cross-platform part (target platforms were iOS, OS X and Windows; obviously
not focussed on Windows at this point), the code clarity and ease with which I
can change data structures makes this approach so much better.

Are you guys looking at supporting Windows/C#/.NET at this stage, because
while I don't develop much software for it, it does come up occasionally, and
it would be good to use it throughout.

~~~
timanglade
Absolutely. We’re good friends with Unity, know lots of people at Microsoft
and have a ton of respect for what Xamarin is doing, so we’d love to support
the whole .Net ecosystem soon. We’re a small team with limited resources so we
have to prioritize this vs. sync vs. core work vs. improving iOS & Android but
we’ll try to all of these things as quickly as possible. Thanks for being a
user and thanks for the kind words :)

~~~
pm
I'm in no hurry, and I'm sure most people would agree that they'd rather see a
database improve stability than branch out too fast to new platforms. Keep up
the good work!

------
bnr
It looks like all I/O happens synchronously, which means you generally should
not run that on Android's main thread. You could just warp all interactions in
AsyncTasks, but that's cumbersome. Do you consider adding an async API with
callbacks on the main thread?

~~~
timanglade
Definitely. We’re considering adding an async mode for individual
transactions, but that opens a few issues in terms of consistency and error-
handling, and we’d definitely want to address those if we offer that method in
the API. For now we think the best route is to let people defer the writes
themselves since you know best when the write will be executed and what
conditions may arise, but you’re not the first person to ask so we’ll
definitely take another, harder look at adding this.

------
V-2
Your JavaDocs miss a rather important information that Java SDK needs to be
switched from 1.6 to at least 1.7 (in Android Studio, under Project Settings)
for the thing to work! Otherwise it can't be run:

Error:Exception thrown while constructing Processor object:
io/realm/processor/RealmProcessor : Unsupported major.minor version 51.0

------
pdpi
The "a replacement for SQLite & Core Data" description confuses me.

Is this a SQLite replacement, in that it is its own database, or a CoreData
replacement, in that it's "just" a nice API over some other persistence layer
(afaik, CoreData gives you a nice consistent API over a number of concrete
persistence implementations, with SQLite being one such implementation)

~~~
timanglade
Hi, I wrote that tagline so maybe I can explain the rationale. We initially
called ourselves “a database that runs directly inside phones, tablets &
wearables” but received some ridicule for that as it sounded like we didn’t
expect our readers/users to know what a mobile/embedded database was. We
iterated a few times until we found this description, where we explain that we
replace both low-level DBs like SQLite and high-level abstractions like ORMs
or Core Data (because we have our own object-interface built in), while
highlighting the two solutions we replace most often on Android & iOS
respectively. I agree it’s still somewhat confusing and your analysis is spot
on. We’ll try to iterate on this tagline a bit more!

~~~
pdpi
So you actually _do_ provide your own db then?

I'd love to know a bit more about this. What drove the decision to roll your
own? Seeing as how SQLite is pretty mature and widely deployed, my first
instinct if I wanted to tackle this problem would just have been to write the
best damn ORM I could on top of SQLite.

~~~
timanglade
Yes we do have our own db. We love SQLite to death but we just saw an
opportunity to start fresh, with a modern design that leverages bitpacking,
caching & vectorization, and would yield more API & performance benefits than
the ceiling most ORMs seems to have hit on iOS & Android. I personally believe
that new databases should always be created as a last resort, but in this case
I think the amount of apps being built and the problems people we talked to
routinely ran into while using SQLite and its ORMs justified this drastic
decision.

------
Ilios
Anything that will reduce the API hell that is working with SQLite on Android
is worth a second look. Better speed is just icing on the cake.

------
sungeuns
I saw Realm's speak at Deview 2014 conference in South Korea, and they
released android version during the presentation that introduce about Realm.
When you guys opened up the terminal and deployed web service with android
version during the seminar, It feels very impressive. Great job guys! :)

~~~
timanglade
Thanks for the kind words! Come say hi on 10/6
[http://onoffmix.com/event/33885](http://onoffmix.com/event/33885) or
[https://www.facebook.com/groups/realmkr](https://www.facebook.com/groups/realmkr)
;)

------
annoia
It's great to finally see a serious alternative for data storage on Android,
and not just one wrapping SQLite at that. While you may not be completely sold
on Realm, competition is always a good thing, and from what they are showing,
they're definitely bringing that - both on speed and usability.

------
orta
Where does the 20,000 iOS users stat come from? I think it's really cool what
Realm is doing.

~~~
timanglade
Hi orta! The estimate is calculated from a mix of indicators: # of downloads,
# of forks on Github, traffic to our docs, apps on GitHub, apps on the App
Store and a few other things, using the same kind of math MongoDB and others
have been using to publish this sort of stats in the past (it’s not cumulative
at all, and there’s a healthy safety ratio built into the math to provide a
very conservative estimate). Of course, this calculation leaves out important
sources for which we do not have stats, such as Dash docs visits, people
downloading from the same company/proxy — and CocoaPod downloads ;)

~~~
mserdarsanli
This is a non-answer.

------
mahyarm
Is realm planning to make a c++ interface version, seeing how it's made in
C++? A lot of cross platform cores use C++ since it Works Everywhere(tm) as an
FFI to other languages & platforms.

~~~
brmunk
Absolutely! That's actually already there. Even with nice expression based
query syntax - looks like natural language :-) We havn't released it though
since we plan to rewamp it into a more object oriented interface like in ObjC,
Swift and Java. But if you really wanted to, nothing prevents you from using
it (the .h files are there), except there is little documentation and the API
will likely change. But yes, definitely it will come fully supported.

The nice thing is you can then make have e.g. common C++ code shared between
your mobile app platforms (as quite a few do), and share state/data easily
between C++ & Java or C++ & ObjC/Swift in one app. No fuss, one API, one
shared datamodel, fully threadsafe between languages.

Would that be useful?

~~~
mahyarm
Oh you could seamlessly-ish share data between c++ cross platform and
java/swift? That would be pretty useful!

So this kind of flow would be pretty simple right?

1\. C++ cross-platform layer receives a text message, records it in the
realmDB.

2\. Java/ObjC UI watcher on that realmDB table automatically gets a callback
update.

3\. UI gets updated with the new message being displayed.

4\. The app gets killed because of a crash, the new message is still safely
recorded in the realmDB, user sees it on app relaunch.

~~~
timanglade
Yes, you should be able to seamlessly share the data from multiple processes &
languages at the same time already via the .realm file to achieve what you
describe. No need to wait for a C++ release :) We do have a bug right now with
inter-process synchronization but I believe it should be handled soon.

------
AmelnCam
I usually use the following code for this purpose: public void
testBatchInserts() throws PerformanceTestException { SQLiteStatement stmt =
db.compileStatement("INSERT INTO " \+ EmployeeDatabaseHelper.TABLE_EMPLOYEES +
" VALUES(?1, ?2, ?3, ?4)");

    
    
            db.beginTransaction();
            for (int row = 0; row < getNumInserts(); row++) {
                stmt.clearBindings();
                stmt.bindString(2, getEmployeeName(row));
                stmt.bindLong(3, getEmployeeAge(row));
                stmt.bindLong(4, getEmployeeHiredStatus(row));
                stmt.executeInsert();
            }
            db.setTransactionSuccessful();
            db.endTransaction();

------
dedene
That's awesome news! Does someone have an idea on how you would store dynamic
data (think document oriented / json) and still run queries on the different
fields?

~~~
timanglade
We do have an alternative, dynamic API that we don’t expose too much to reduce
confusion. You can see a bit of it at work in the migration example:
[https://github.com/realm/realm-
java/tree/master/examples/mig...](https://github.com/realm/realm-
java/tree/master/examples/migrationExample) (Just FYI, it’s likely we’ll
simplify it extensively in the next few weeks.)

------
kazuki
Faster, more understandable code and less disk space. It's great and I wonder
how this miracle possible.

~~~
timanglade
Ritual sacrifices, mostly. Just kidding ;) For the “faster” and “less disk
space” parts, we use a lot of standard techniques like bitpacking,
compactionless b-trees and other things that have been designed in the past 10
years — we’ll blog more about that stuff very soon. The “understandable code”
part can probably be explained by the fact we focused on that extensively
during implementation: we did lot of API revisions, gathered lots of feedback
in private beta — and we still have a long way to go!

~~~
kazuki
Cool. I love reading such tech blog post.

------
nicpottier
Looks interesting for sure, are you going to update the Pricing page for
Android?

Same terms there?

~~~
timanglade
Oops! Just updated the page. Thanks for the heads-up!
[http://realm.io/pricing/](http://realm.io/pricing/)

------
V-2
So data is persisted totally independently of the SQLite engine? Straight in
the file system?

~~~
brmunk
Absolutely - it's a totally new C++ fast nosql fully ACID database underneath.
The database has been in development for the past 3 years, so it's not just a
quick hack :-)

------
bravura
Can you use Realm with Phonegap applications?

~~~
timanglade
Technically yes, you could write your own JavaScript wrappers using the bridge
(and alias the API differences between iOS and Android) but that’s probably
cumbersome at this point. We do hope to make a version of Realm for Phonegap
soon.

~~~
cwyers
What about Xamarin?

~~~
timanglade
We have a .Net wrapper internally and we’re really looking forward to getting
back to work on it. No commitments on the order but a few of us who really
like it to be the next platform we target (including Xamarin, Unity) now that
Android is out :)

