Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Realm for Android (realm.io)
108 points by _bkgg on Sept 30, 2014 | hide | past | favorite | 53 comments



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

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.


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...)


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.



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 :(


This is good feedback — we definitely expect to be polishing the API quite a bit in the weeks to come, just like we did on iOS>

You have to use Realm.createObject because objects are strongly tied to one Realm at a time. We could introduce standalone objects you can create with regular constructors but you’d be a really heft performance hit there.

RealmLists are mostly used to model relationships at this point, so you could add them to a another model like (http://realm.io/docs/java/0.70.1/#relationships) although eventually we do want to introduce standalone RealmLists.

What would you expect to use multiple RealmObjects in a single RealmList for? (Just so we can learn from your use-case.)


I was trying to add in a Realm test to a benchmarking project I already have set up to see how quickly I can retrieve a list of Stack Exchange sites from disk/db/etc, the Site model is laid out here: https://api.stackexchange.com/docs/types/site -- each Site object can have anywhere from 0 to N related_site objects, which in my current model I just have as a RelatedSite[], since my test case is running all the different ways to cache/read at the same time I was trying to make a method in my RealmObject version of Site that takes in a regular Site object and transforms everything over, but I couldn't figure out how to translate the RelatedSite[] array into a RealmList<RelatedSite> without actually iterating through every one and recreating them by hand.


Thank you for bringing the subject up! Importing data from JSON in a painless way is very high on the priority list. Right now we don't have an elegant solution for your specific use-case, but we're working on it so stay tuned! Please feel free to join us in the mailing list as we would love to hear more about your project and help with it if possible!


Thanks for the heads up! We will address that right away.

Also, one of the examples (GridViewExample) in the release reads JSON data with GSON.


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 where seepel finds SQLite to be more than twice as fast as Realm after that one change to the benchmark.


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.


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.


That was a totally 100% fair point you made when we launched for iOS, and something we had completely overlooked. Your comment immediately prompted us to update our bench code to reuse compiled statements and, we’ve been using updated charts to document our iOS performance since then (e.g.: https://speakerdeck.com/timanglade/realm-overview-at-the-sil...). See other comment (https://news.ycombinator.com/item?id=8390541) regarding our performance on Android — we do reuse compiled statements.

EDIT: typos.

EDIT 2: clearly referencing that this message was about iOS and pointing to the other comment for Android.


Cool, thanks! I've mostly been looking at the iOS announcement page, which hasn't changed - harder to track down other materials you've used for promotion :/ Not that an old blog post is a great barometer of such things, of course.

Thanks again for looking into it and updating the material - far too many groups just gloss over (glaring) problems with their micro benchmarks, and it just sours all their future claims. Glad you're not one of them :)


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.


I have just had a look at realm doc, but compared to core data, it seems to provide a MUCH cleaner api, especially regarding threading and transaction ( which i think i'm only starting to get right after having coded with core data for two years).

I do agree that net syncing would definitely be a killer feature for me as well, but it's probably not the case for the average project ( which probably uses custom web services for crud on the serve side).


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... [2]: http://developer.android.com/training/basics/activity-lifecy...


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


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


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.


The main difference is that with Parcelable you have two versions of your object (one persisted on disk and one in memory) while with Realm you are always working with your real data, not a representation of it.


You can always just put the model id (or some other way to requery) in the Bundle and look it up again after the configuration change.


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.


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/


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.


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 :)


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!


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?


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.


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)


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!


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.


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


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.


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! :)


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


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 ;)


This is a non-answer.


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.


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?


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.


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?


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


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!


Cool. I love reading such tech blog post.


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


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 :-)


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

Same terms there?


Sure - terms are the same. Free for all!


Can you use Realm with Phonegap applications?


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.


What about Xamarin?


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();




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: