When you ask Realm to compact itself, it creates a copy (without preserving the empty space), then overwrites the current DB file with the copy. As such, it only works if there are no open Realm instances in any processes. Rewriting the database contents takes time, and is an IO operation. Therefore, theoretically, the best practice would be to not call Realm.compactRealm(config)
on the UI thread.
The theoretical answer would be to call it on a background thread, and wait for it to finish before doing any Realm operations, but that’s rather uncommon. What we did way back when was when the application was finished (activity count == 0), we called Realm.compactRealm()
(as best effort). There is a realmConfiguration.compactOnLaunch()
call, but technically that is only safe (non-blocking) to use, if using Realm.getInstanceAsync()
.
The best thing one can do is not have Realm open on multiple non-looper background threads at the same time, as Realm does allow reclaiming empty blocks within the file, it just doesn’t automatically remove said empty blocks (a file grows and can be reused, but it won’t decrease without compacting).
As for LiveData, I ended up writing https://github.com/Zhuinden/realm-monarchy, which now (7.0.0+) allows using frozen results from a background looper thread. I do think it’s a bit late, this would have been a game changer 3 years ago.