Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Safe vs Deep integration of Realm

Viraj Tank
October 15, 2016

Safe vs Deep integration of Realm

Viraj Tank

October 15, 2016
Tweet

More Decks by Viraj Tank

Other Decks in Programming

Transcript

  1. Sociomantic Labs Dev Fest Hamburg 2016 #devfestHH Droidcon Vienna 2016

    #droidconVie Viraj Tank @viraj49 Droidcon London 2016 #droidconUK Mobile Era Oslo 2016 #mobileEra
  2. Operation ORMLite Realm Init 92 ms 30 ms Write -

    20k 1692 ms 1011 ms Read - 2k 2716 ms 410 ms Performance
  3. Download /* Project level build.gradle file */ classpath "io.realm:realm-gradle-plugin:2.1.1" /*

    Application level build.gradle file */ apply plugin: 'realm-android' ~1750 method counts ~800 kilobytes
  4. Init & Config Realm.init(this); RealmConfiguration config = new RealmConfiguration .Builder()

    .build(); Realm.init(this); RealmConfiguration config = new RealmConfiguration .Builder() .name("gitHubDB") .build(); Realm.init(this); RealmConfiguration config = new RealmConfiguration .Builder() .name("gitHubDB") .encryptionKey(key) .build(); Realm.init(this); RealmConfiguration config = new RealmConfiguration .Builder() .name("gitHubDB") .encryptionKey(key) .deleteRealmIfMigrationNeeded() .build(); Realm.init(this); RealmConfiguration config = new RealmConfiguration .Builder() .name("gitHubDB") .encryptionKey(key) .deleteRealmIfMigrationNeeded() .build(); Realm.setDefaultConfiguration(config); Realm realm = Realm.getDefaultInstance();
  5. /* used for all (realm + json + view) */

    @Getter public class GitHubUser { private String login; private int id; private String avatar_url; } /* used for all (realm + json + view) */ @Getter public class GitHubUser extends RealmObject { private String login; private int id; private String avatar_url; } /* used for all (realm + json + view) */ @Getter public class GitHubUser extends RealmObject { @PrimaryKey private String login; private int id; private String avatar_url; } Model
  6. MVP (model view presenter ) Clean architecture Realm + RxJava

    Retrofit Dagger Butterknife Retrolambda Lombok
  7. Presenter public class Presenter { private View mView; public class

    Presenter { private View mView; private DataSource mDataSource; public class Presenter { private View mView; private DataSource mDataSource; public void loadData() { mDataSource .getData() public class Presenter { private View mView; private DataSource mDataSource; public void loadData() { mDataSource .getData() .subscribeOn(computationThread()) public class Presenter { private View mView; private DataSource mDataSource; public void loadData() { mDataSource .getData() .subscribeOn(computationThread()) .observeOn(mainThread()) public class Presenter { private View mView; private DataSource mDataSource; public void loadData() { mDataSource .getData() .subscribeOn(computationThread()) .observeOn(mainThread()) .subscribe(mData -> mView.setData(mData)); } }
  8. public class DataSource { private Cache mCache; private Dao mDao;

    private Retrofit mRetrofit; public class DataSource { private Cache mCache; private Dao mDao; private Retrofit mRetrofit; private Observable<List<GitHubUser>> fromCache() { return Observable.fromCallable(() -> mCache.getData()); } public class DataSource { private Cache mCache; private Dao mDao; private Retrofit mRetrofit; private Observable<List<GitHubUser>> fromCache() { return Observable.fromCallable(() -> mCache.getData()); } private Observable<List<GitHubUser>> fromRealm() { return Observalbe.fromCallable(() -> mDao.getData()); } public class DataSource { private Cache mCache; private Dao mDao; private Retrofit mRetrofit; private Observable<List<GitHubUser>> fromCache() { return Observable.fromCallable(() -> mCache.getData()); } private Observable<List<GitHubUser>> fromRealm() { return Observalbe.fromCallable(() -> mDao.getData()); } private Observable<List<GitHubUser>> fromRetrofit() { List<GitHubUser> gitHubUserList = mRetrofit.getData(); mDao.storeData(gitHubUserList); return Observable.just(gitHubUserList); } } Data Source
  9. DAO public class Dao { Realm mRealm; public class Dao

    { Realm mRealm; public List<GitHubUser> getData() { public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm.where(GitHubUser.class) public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm.where(GitHubUser.class).findAll(); } public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm.where(GitHubUser.class).findAll(); } public void storeData(List<GitHubUser> gitHubUserList) { public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm.where(GitHubUser.class).findAll(); } public void storeData(List<GitHubUser> gitHubUserList) { mRealm.executeTransaction(mRealm1 -> public class Dao { Realm mRealm; public List<GitHubUser> getData() { return mRealm.where(GitHubUser.class).findAll(); } public void storeData(List<GitHubUser> gitHubUserList) { mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); }
  10. “ Realm access from incorrect t hread. Realm objects can

    only b e accessed on the thread they w ere created.
  11. DAO public class Dao { Realm mRealm; public List<GitHubUser> getData()

    { return mRealm.where(GitHubUser.class).findAll(); } public void storeData(List<GitHubUser> gitHubUserList) { mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); }
  12. Drawing Board 1. Don't inject Realm 2. Don't pass RealmResults

    across threads “ Make an in memory copy of results and pass it to Presenter. - Safe integration “ Query the data in Presenter itself on main thread. - Deep integration
  13. DAO public class Dao { public void storeData(List<GitHubUser> gitHubUserList) {

    public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public List<GitHubUser> getData() { public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public List<GitHubUser> getData() { Realm mRealm = Realm.getDefaultInstance(); public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public List<GitHubUser> getData() { Realm mRealm = Realm.getDefaultInstance(); List<GitHubUser> gitHubUserList = mRealm.where(GitHubUser.class) .findAll()); public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public List<GitHubUser> getData() { Realm mRealm = Realm.getDefaultInstance(); List<GitHubUser> gitHubUserList = mRealm.copyFromRealm( mRealm.where(GitHubUser.class) .findAll()); public class Dao { public void storeData(List<GitHubUser> gitHubUserList) { Realm mRealm = Realm.getDefaultInstance(); mRealm.executeTransaction(mRealm1 -> mRealm1.insertOrUpdate(gitHubUserList)); mRealm.close(); } public List<GitHubUser> getData() { Realm mRealm = Realm.getDefaultInstance(); List<GitHubUser> gitHubUserList = mRealm.copyFromRealm( mRealm.where(GitHubUser.class) .findAll()); mRealm.close(); return gitHubUserList; } }
  14. public class Presenter { private View mView; private Realm mRealm;

    private DataSource mDataSource; public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) .filter(realmResults -> realmResults.size() > 0) .subscribe(gitHubUsers -> mView.setData(gitHubUsers)); } public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) .filter(realmResults -> realmResults.size() > 0) .subscribe(gitHubUsers -> mView.setData(gitHubUsers)); } public void loadData() { mDataSource .getData() .subscribeOn(getComputationThread()) .observeOn(getMainThread()) public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) .filter(realmResults -> realmResults.size() > 0) .subscribe(gitHubUsers -> mView.setData(gitHubUsers)); } public void loadData() { mDataSource .getData() .subscribeOn(getComputationThread()) .observeOn(getMainThread()) .subscribe(statusValue -> statusValue); } public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) .filter(realmResults -> realmResults.size() > 0) .subscribe(gitHubUsers -> mView.setData(gitHubUsers)); } public void loadData() { mDataSource .getData() .subscribeOn(getComputationThread()) .observeOn(getMainThread()) .subscribe(statusValue -> statusValue); } public void unSubscribe() { public class Presenter { private View mView; private Realm mRealm; private DataSource mDataSource; public void bind() { mRealm = Realm.getDefaultInstance(); mRealm.where(GitHubUser.class) .findAllAsync() .asObservable() .filter(RealmResults::isLoaded) .filter(RealmResults::isValid) .filter(realmResults -> realmResults.size() > 0) .subscribe(gitHubUsers -> mView.setData(gitHubUsers)); } public void loadData() { mDataSource .getData() .subscribeOn(getComputationThread()) .observeOn(getMainThread()) .subscribe(statusValue -> statusValue); } public void unSubscribe() { mRealm.removeAllChangeListeners(); mRealm.close(); } }
  15. Safe 1. Easy 2. Realm on comp-thread 3. Pluggable module

    4. Easy to test & debug 5. Minimal structure change 6. Minimal refactoring 7. Clean Architechture Deep 1. Auto update feature 2. Faster queries 3. Less memory utilization Integration