ã¬ã«ã ã¯ãã¢ãã€ã«ïŒã ãã§ãªãïŒéçºè ã®éã§é·ãéç¥ãããŠããŸãã æ®å¿µãªãããRuNetã«ã¯ãã®ããŒã¿ããŒã¹ã«é¢ããèšäºã¯ã»ãšãã©ãããŸããã ãã®ç¶æ³ãä¿®æ£ããŸãããã
1幎åããããžã§ã¯ãã®build.gradleã«æ¬¡ã®è¡ã衚瀺ãããŸããã
classpath "io.realm:realm-gradle-plugin:0.87.5"
ä»å¹ŽãRealmã³ãŒãã¯ããŒãžã§ã³3.3ã«æé·ããå€ãã®æ©èœãååŸããå€æ°ã®ãã°ãä¿®æ£ããæ°ããæ©èœãå®è£ ããã¯ã©ãŠãããã¯ãšã³ããåãåããŸããã Andoroidéçºã®çŸå®ã«ãããRealmã«ã€ããŠè©³ãã説æããããã䜿çšãããšãã«çãã埮åŠãªãã€ã³ãã«ã€ããŠèª¬æããŸãã
å
容
- ç§éã«ã€ããŠ
- ã¹ã¿ãŒãã¢ãããšããŠã®ã¬ã«ã
- ããŒã¿ããŒã¹ãšããŠã®ã¬ã«ã
- ãããŒã¯ãŒã«ã
- ä»ã®ããŒã¿ããŒã¹ãšã®æ¯èŒ
- ã©ã€ããªããžã§ã¯ã-åæèªã¿åã
- ã©ã€ããªããžã§ã¯ã-éåæèªã¿åã
- ã¬ã«ã ãªããžã§ã¯ãã®äž»ãªæ©èœ
- ååŒ
- åæãã©ã³ã¶ã¯ã·ã§ã³
- éåæãã©ã³ã¶ã¯ã·ã§ã³
- ã¬ã«ã ãéã/éãã
- éç¥ãRxJava
- ãã«ãã¹ã¬ãããšéåæ
- ãã¹ãäž
- 1ã€ã®ã¬ã«ã ã¯è¯ããã3ã€ã®ã¬ã«ã ã¯è¯ã
- ç¶æ¿ãšå€å
- ã³ããªã³
- ã¬ã«ã ã¢ãã€ã«ãã©ãããã©ãŒã
- ãããã°
- 建ç¯
- 䟿å©ãªãªã³ã¯
- ãããã«
ç§éã«ã€ããŠ
ããŒã å ã§ã®ã³ãã¥ãã±ãŒã·ã§ã³çšã®ã¢ããªã±ãŒã·ã§ã³ãé»å ±ãšã¹ã©ãã¯ã®ã¯ãã¹ãéçºããŠããŸãã Androidã¢ããªã±ãŒã·ã§ã³ã¯Kotlinã§èšè¿°ãããŠãããæåãããªãã©ã€ã³åªå ã¢ãããŒãã䜿çšãããŠããŸããã ç»é¢ã«è¡šç€ºããããã¹ãŠã®ããŒã¿ããã£ãã·ã¥ããåãåºããããšãã ããã€ãã®ç°ãªãããŒã¿ããŒã¹ãè©ŠããåŸãRealmã«èœã¡çãã1幎éã¢ã¯ãã£ãã«äœ¿çšããŸããã ãã®èšäºã¯ãã¬ã«ã ã®äœ¿çšã«é¢ããå éšææžããçãŸããŸããã ãã®èšäºã¯ããã¥ã¡ã³ãã®ç¿»èš³ã§ã¯ãªããå®å šãªèª¬æã®ãµãããããã®ã§ã¯ãªããã¬ã·ãã®ã³ã¬ã¯ã·ã§ã³ãšåŸ®åŠãªãã€ã³ãã®åæã§ãã å®å šã«ç解ããããã«ã å ¬åŒããã¥ã¡ã³ããèªãããšã匷ããå§ãããŸã ã ç§ãã¡ã®çµéšãšä»å¹Žã®åé¡ç¹ã«ã€ããŠèª¬æããŸãã ãã®èšäºã®ã³ãŒãã¯ãã¹ãŠKotlinã§æžãããŠããŸããGithubã§èŠã€ããããšãã§ããŸãã
ã¹ã¿ãŒãã¢ãããšããŠã®ã¬ã«ã
RealmãäŒç€ŸãšããŠè©±ããšã2011幎ã«èšç«ããããã³ããŒã¯ã®ã¹ã¿ãŒãã¢ããã§ãã 以åã¯ããããžã§ã¯ãã¯tight.dbãšåŒã°ããŠããŸããã ãã®ååšã®éã«ã2900äžãã«ã®æè³ãéããŸããã å瀟ã¯ã Realm Mobile Platformã«åºã¥ããŠåçãäžããããšãèšç»ããŠããŸããããŒã¿ããŒã¹èªäœã¯ç¡æã§ãªãŒãã³ãœãŒã¹ã§ãã Realm for Androidã¯2014幎ã«ç»å Žãããã以æ¥åžžã«é²åããŠããŸãã äžéšã®ã¢ããããŒãã¯åŸæ¹äºææ§ãå£ããŸãããä¿®æ£ã¯éåžžã«ç°¡åãã€è¿ éã«è¡ããŸãã
ããŒã¿ããŒã¹ãšããŠã®ã¬ã«ã
ã¬ã«ã ã¯ãããã€ãã®ãã©ãããã©ãŒã çšã®ããŒã¿ããŒã¹ã§ãã 圌ãã¯èªåèªèº«ã«ã€ããŠæžããŠããŸãïŒ
Realm Mobile Platformã¯ãã¢ããªã±ãŒã·ã§ã³çšã®æ¬¡äžä»£ããŒã¿ã¬ã€ã€ãŒã§ãã ã¬ã«ã ã¯ããªã¢ã¯ãã£ããã³ã³ã«ã¬ã³ããããã³è»œéã§ãããã©ã€ãã®ãã€ãã£ããªããžã§ã¯ããæäœã§ããŸãã
èŠããã«ãããã¯AndroidïŒJavaãKotlinïŒãiOSïŒObjective-CãSwiftïŒãXamarinïŒCïŒïŒãããã³JavaScriptïŒReact NativeãNode.jsïŒã®ãã€ãã£ãno-sqlããŒã¿ããŒã¹ã§ãã
ãŸãããã¹ãŠã®ãœãŒã¹ããã®ããŒã¿ãåæã§ããããã¯ãšã³ãããããŸãã
éèŠãªæ©èœã®ãã¡ã ãŒãã³ã㌠ã MVCC ãããã³ACIDã«æ³šç®ãã䟡å€ããããŸãã çµã¿èŸŒã¿ã®é³è åããã³ããŒã¿ã¯ã¬ã³ãžã³ã°ã¡ã«ããºã ã¯ãããŸããã
Realmã«ã¯ã éåžžã«åªããããã¥ã¡ã³ããšgithubã®å€ãã®äŸããããŸãã
ã¬ã«ã ã®åŸæ¥å¡ã¯å®æçã«StackOverflowãç£èŠããŠããŸãããgithubã§åé¡ãååŸããããšãã§ããŸãã
ãããŒã¯ãŒã«ã
Androidã®Hello Worldã¯æ¬¡ã®ãšããã§ãã
build.gradleã«è¿œå
build.gradle (Project level) classpath "io.realm:realm-gradle-plugin:3.3.0" build.gradle (App level) apply plugin: 'realm-android'
ã¢ããªã±ãŒã·ã§ã³ã§ãã¬ã«ã æ§æãæ§æããŸã
Realm.init(this) val config = RealmConfiguration.Builder() .build() Realm.setDefaultConfiguration(config)
ãããŠãããŒã¿ããŒã¹ã®æäœãéå§ã§ããŸãã
val realm = Realm.getDefaultInstance() realm.executeTransaction { realm -> val dataObject = realm.createObject(DataObject::class.java) dataObject.name = "A" dataObject.id = 1 } val dataObject = realm.where(DataObject::class.java).equalTo("id", 1).findFirst() dataObject.name // => A realm.executeTransaction { realm -> val dataObjectTransaction = realm.where(DataObject::class.java).equalTo("id", 1).findFirst() dataObjectTransaction.name = "B" } dataObject.name // => B
ä»ã®ããŒã¿ããŒã¹ãšã®æ¯èŒ
ããã«ã¯ã2016幎4æ8æ¥ä»ã®èšäºãããã Realmãå«ãAndroidã®9ã€ã®ORMãæ¯èŒããŠããŸãã é åã¯å é ã«ãããããã«ã°ã©ãã£ãã¯ããããŸãïŒ
ä»ã®ORMãšã®æ¯èŒ
Realmã¯ããã®Webãµã€ãã§ä»¥äžã®çµ±èšãæäŸããŠããŸã ã
ã¬ã«ã ããã®ãã£ãŒã
èæ ®ããªããã°ãªããªã3ã€ã®äž»ãªæ©èœããããŸãã
ã©ã€ããªããžã§ã¯ã-ã¬ã«ã ããååŸãããã¹ãŠã®ãªããžã§ã¯ãã¯ãå®éã«ã¯ããŒã¿ããŒã¹ã®ãããã·ã§ãã ãã®ããããŒãã³ããŒãå®çŸãããŸãïŒãªããžã§ã¯ãã¯ããŒã¿ããŒã¹ããã³ããŒãããŸããïŒ
ãã©ã³ã¶ã¯ã·ã§ã³-æ·»ä»ãããããŒã¿ãªããžã§ã¯ãã«å¯Ÿãããã¹ãŠã®å€æŽã¯ããã©ã³ã¶ã¯ã·ã§ã³å ã§è¡ãå¿ èŠããããŸã
éã\éãã-ã€ã³ã¹ã¿ã³ã¹ããŒã¿ããŒã¹ãéã\éããå¿ èŠ
ã©ã€ããªããžã§ã¯ã
ã¬ã«ã ã®ãã¹ãŠã®ãªããžã§ã¯ãã¯ãåæãŸãã¯éåæã§åä¿¡ã§ããŸãã
åæèªã¿åã
fun getFirstObject(realm: Realm, id: Long): DataObject? { return realm.where(DataObject::class.java).equalTo("id", id).findFirst() }
Realmã¡ãœãããåŒã³åºãããªããžã§ã¯ããŸãã¯nullãååŸãããŸã§ã¹ã¬ããããããã¯ããŸãã ä»ã®ã¹ã¬ããã§åä¿¡ãããªããžã§ã¯ãã¯äœ¿çšã§ããªããããã¡ã€ã³ã¹ã¬ããã§äœ¿çšããã«ã¯ãuiããããã¯ããããéåæèŠæ±ã䜿çšããå¿ èŠããããŸãã 幞ããªããšã«ãRealmã¯ãªããžã§ã¯ãèªäœã§ã¯ãªããããã·ãæäŸããããããã¹ãŠãååã«è¿ éã«è¡ãããŸãã åé åŸããã«ãªããžã§ã¯ããæäœã§ããŸãã
éåæèªã¿åã
éåžžã«æçœãªã±ãŒã¹ã ãã®ã³ãŒãã§äœãèµ·ãããšæããŸããïŒ
val firstObject = realm.where(DataObject::class.java).findFirstAsync() log(firstObject.id)
æ£è§£ïŒãšã©ãŒjava.lang.IllegalStateExceptionãçºçããŸã
éåæèªã¿åãã§ã¯ããªããžã§ã¯ããããã«ååŸã§ããŸãããããŒããããŸã§æäœã§ããŸããã isLoadedïŒïŒé¢æ°ã䜿çšããŠããã確èªããããããããã³ã°ããŒãïŒïŒé¢æ°ãåŒã³åºãå¿ èŠããããŸãã ããªãäžå¿«ã«èŠããã®ã§ãããã§rxã䜿çšããããšããå§ãããŸãã ç£èŠå¯èœã«å€æããOnNextã§ããŒãããããªããžã§ã¯ããååŸããŸãã éåææäœã¯ãã«ãŒããŒã䜿çšããã¹ãââãªãŒã ã§ã®ã¿äœ¿çšã§ããŸãã
fun getObjectObservable(realm: Realm, id: Long): Observable<DataObject> { return realm.where(DataObject::class.java).findFirstAsync().asObservable() }
ã¬ã«ã ãªããžã§ã¯ãã®äž»ãªæ©èœ
- ããŒã¿ããŒã¹ããã®ãªããžã§ã¯ãã®ååŸã¯éåžžã«é«éã§ãããéã·ãªã¢ã«åã¯è¡ãããŸããããã£ã¹ã¯ããã®èªã¿åãã¯ç¹å®ã®ãã£ãŒã«ãã«ã¢ã¯ã»ã¹ãããšãã«ã®ã¿çºçããŸã
- ãã®ããããã¹ãŠã®ãã£ãŒã«ãããã©ã€ããŒãã«ããã²ãã¿ãŒãä»ããŠã¢ã¯ã»ã¹ããå¿ èŠããããŸãã
- CopyFromRealmïŒïŒã¡ãœãã-éåžžã®ORMãšåæ§ã«ãã¢ã³ã¿ã€ããããå®å šã«ã¢ã»ã³ãã«ããããªããžã§ã¯ããååŸã§ããŸãã 確ãã«ããã¹ãŠã®Realmãããã¯å©çšã§ããªããªããŸãã å ¥åã¯ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã®æ·±ãã§ãããã©ã«ãã§ã¯MAX_INT
- ãããã¬ãŒã§ã¯ããã¹ãŠã®ãã£ãŒã«ãããã«ã«ãªããŸãã å€ãååŸããã«ã¯ãã²ãã¿ãŒãéããŠé£çµ¡ããå¿ èŠããããŸã
- ãã¹ãŠã®Liveãªããžã§ã¯ããã€ãŸãã©ã€ãã å€æŽã¯åäžã®ã¹ã¬ããå ã§å³åº§ã«äŒæããŸãã 以äžã®ããè€éãªã±ãŒã¹ãåç §ããŠãã ããïŒãã«ãã¹ã¬ããïŒã
- ãªããžã§ã¯ãã¯ãã£ãŒã«ãã§ãã£ã«ã¿ãªã³ã°ããããã£ãŒã«ãã®ååãæååãšããŠæã§ç€ºããŸãã ããšãã°ã.equalToïŒ "id"ã1ïŒã®ããã«ãªããŸãã ããã«ããããªãã¡ã¯ã¿ãªã³ã°ãè€éã«ãªãããã£ã«ã¿ãªã³ã°çšã®ãã£ãŒã«ãåã«ãšã©ãŒãçºçããŸãã æ®å¿µãªãããRealmã¯ãã£ãŒã«ãåãæã€å€æ°ãçæããªããããé¢æ°å
ã®ãã¹ãŠã®éžæãé衚瀺ã«ããæ¹ãé©åã§ãã
fun findFirstDataObject(id: Long, realm: Realm) : DataObject = realm.where(DataObject::class.java).equalTo("id", id).findFirst()
ãŸãã¯cmelchiorãã£ãŒã«ãåãžã§ãã¬ãŒã¿ãŒã䜿çšããŸã
- ãã®ç¹ã¯ãèšäºã®å·çæç¹ã§å€æŽãããŠããŸãïŒãããžã§ã¯ãã®éçºæ¹æ³ã®é®®æãªäŸïŒ
ãªããžã§ã¯ããå€æŽãããšãã«DiffUtilã䜿çšããããšã¯äžå¯èœã§ããããªããžã§ã¯ããã©ã®ãã£ãŒã«ããå€æŽããããç解ããããšã¯äžå¯èœã§ãã ã€ãŸã ãªããžã§ã¯ãã®å€æŽã«é¢ããéç¥ãåãåã£ãå Žåãäœãå€æŽãããããç解ããããšã¯äžå¯èœã§ãã ããã¯ãäž¡æ¹ã®ãªããžã§ã¯ãïŒå€ããã®ãšæ°ãããã®ïŒãã©ã€ããªããžã§ã¯ãã§ãããåãããŒã¿ãåç §ããŠããããã§ãããããã¯åžžã«çãããªããŸãã
çŸåš ïŒ RealmObjectChangeListenerã䜿çšããŠãäœãå€æŽãããããç解ã§ããŸã ã
RealmObjectChangeListenerPerson p = realm.where(Person.class).findFirst(); p.addChangeListener(new RealmObjectChangeListener<Person>() { @Override public void onChange(Person person, ObjectChangeSet changeSet) { if (changeSet.isDeleted()) { hide(); // Object was deleted } else { // Use information about which fields changed to only update part of the UI if (changeSet.isFieldChanged("name")) { updateName(person.getName()); } } } });
- ãªããžã§ã¯ãã¯ãååŸããã€ã³ã¹ã¿ã³ã¹ã¬ã«ã aãéããŠããéã®ã¿ã¢ã¯ã»ã¹ã§ããŸãã isValidã¡ãœããã§ç¢ºèªã§ããŸãã ç¡å¹ãªãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ãããšãäŸå€ãçºçããŸã
- ãªããžã§ã¯ãã¯ãäœæãããã¹ããªãŒã ã§ã®ã¿äœ¿çšã§ããŸãã å¥ã®ã¹ã¬ããããã¢ã¯ã»ã¹ã§ããŸãããäŸå€ãçºçããŸã
åæ§ã«ãïŒRealmResultïŒãªããžã§ã¯ãïŒã¯ãšãªçµæïŒã®ãªã¹ãã¯Realmã®ãããã·ã§ããããã«ããã次ã®ããã«ãªããŸãã
- ãªã¹ãã¯éåžžã«é«éã§ãå®éã«ã¯æ°ããããŸãã ãã¹ãŠã®é 延ãªã¯ãšã¹ããè€éãªãªããžã§ã¯ãã®å€§èŠæš¡ãªãªã¹ããéåžžã«è¿ éã«ååŸã§ããŸã
- ãªã¹ãã¯èªã¿åãå°çšã§ãããå€æŽæ¹æ³ããããšäŸå€ãçºçããŸã
- ãªããªã ãã¹ãŠã®èŠçŽ ãè¿
éãã€å®äŸ¡ã«åãåãããšãã§ããããŒãžããŒã·ã§ã³ã®åé¡ãå¿ããããšãã§ããŸãã ã¹ã¯ããŒã«ãããšãã¯åžžã«ãªããžã§ã¯ãã®å®å
šãªãªã¹ããæäŸãããªããžã§ã¯ãã«ç§»åãããšãããŒã¿ããŒã¹ãããã°ããååŸãããŸãã ããŒã¿ãããŒãããå¿
èŠãããå Žåã¯ãããŠã³ããŒããéå§ããŠããŒã¿ãååŸããRealmã«ä¿åããŸããå床ãããŒããããèŠçŽ ã®å®å
šãªãªã¹ããååŸããŠè¡šç€ºããŸã
- æè¿ãŸã§ïŒããŒãžã§ã³3.0ããåïŒããªã¹ãã®ãã¹ãŠã®èŠçŽ ã®åæç»ã«åé¡ããããŸããã ã¢ããã¿ã®ãªã¹ãã䜿çšããå Žåã1ã€ã®èŠçŽ ãå€æŽããããšããªã¹ãå
šäœãå®å
šã«åæç»ãããŸãã DiffUtilsã®äœ¿çšãšå€æŽããããªããžã§ã¯ãã®æ¯èŒã¯å€±æããŸãã ãããã¯ã©ã€ããªããžã§ã¯ãã§ãã Realm 3.0ã§ã¯ãDeletionRangesãInsertionRangeãChangeRangesã瀺ãOrderedCollectionChangeSetãç»å ŽããŸããã æçµçã«ãã©ã®ãªããžã§ã¯ããã©ã®ããã«å€åããããç解ã§ããããã«ãªããŸããã
CollectionChangeListenerã®äŸprivate final OrderedRealmCollectionChangeListener<RealmResults<Person>> changeListener = new OrderedRealmCollectionChangeListener() { @Override public void onChange(RealmResults<Person> collection, OrderedCollectionChangeSet changeSet) { // `null` means the async query returns the first time. if (changeSet == null) { notifyDataSetChanged(); return; } // For deletions, the adapter has to be notified in reverse order. OrderedCollectionChangeSet.Range[] deletions = changeSet.getDeletionRanges(); for (int i = deletions.length - 1; i >= 0; i--) { OrderedCollectionChangeSet.Range range = deletions[i]; notifyItemRangeRemoved(range.startIndex, range.length); } OrderedCollectionChangeSet.Range[] insertions = changeSet.getInsertionRanges(); for (OrderedCollectionChangeSet.Range range : insertions) { notifyItemRangeInserted(range.startIndex, range.length); } OrderedCollectionChangeSet.Range[] modifications = changeSet.getChangeRanges(); for (OrderedCollectionChangeSet.Range range : modifications) { notifyItemRangeChanged(range.startIndex, range.length); } } };
ååŒ
ã¬ã«ã ã«ãã€ã³ãããããªããžã§ã¯ãã¯ããã©ã³ã¶ã¯ã·ã§ã³å ã§ã®ã¿å€æŽã§ããŸã;ãã©ã³ã¶ã¯ã·ã§ã³å€ã§å€æŽãããšããšã©ãŒãçºçããŸãã äžæ¹ã§ãããŸã䟿å©ã§ã¯ãããŸãããäžæ¹ã§ãèŠåŸããããã³ãŒãã®ã©ã®éšåã§ããªããžã§ã¯ããå€æŽã§ããŸãããç¹å®ã®ã¬ã€ã€ãŒïŒããŒã¿ããŒã¹ïŒã§ã®ã¿å€æŽã§ããŸãã ãŸããå¥ã®ãã©ã³ã¶ã¯ã·ã§ã³å ã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯çŠæ¢ãããŠããããšãèŠããŠããå¿ èŠããããŸãã
ããªãæ¹æ³ïŒ
val user = database.getUser(1) button.setOnClickListener { user.name = "Test" }
ã§ããããšïŒ
val user = database.getUser(1) button.setOnClickListener { database.setUserName(user, "Test") }
ãã©ã³ã¶ã¯ã·ã§ã³ã¯ãåæããã³éåæã§å®è¡ã§ããŸãã åãªãã·ã§ã³ã詳ããèŠãŠã¿ãŸãããã
åæãã©ã³ã¶ã¯ã·ã§ã³ïŒ
fun syncTransaction() { Realm.getDefaultInstance().use { it.executeTransaction { val dataObject = DataObject() it.insertOrUpdate(dataObject) } } }
beginTransactionãšcommitTransactionã®éã§ãã©ã³ã¶ã¯ã·ã§ã³ãå®è¡ããããšãã§ããŸãããexecuteTransactionã䜿çšããããšããå§ãããŸãã
æ®å¿µãªãããåæãã©ã³ã¶ã¯ã·ã§ã³ã¯onErrorã³ãŒã«ããã¯ããµããŒãããŠããªãããããšã©ãŒåŠçã¯ãŠãŒã¶ãŒã®è²¬ä»»ã§ãã 2016幎6æ以éãonErrorã³ãŒã«ããã¯ã®è¿œå ã«åé¡ããããŸãã
éåæãã©ã³ã¶ã¯ã·ã§ã³
éåæãã©ã³ã¶ã¯ã·ã§ã³ã¯ãasyncTransactionã¡ãœããã«ãã£ãŠããªã¬ãŒãããŸãã ãã©ã³ã¶ã¯ã·ã§ã³ãšã³ãŒã«ããã¯onSuccessãšonErrorãå ¥åã«æž¡ããåºåã§RealmAsyncTaskãªããžã§ã¯ããååŸããŸãããã®ãªããžã§ã¯ãã䜿çšããŠãã¹ããŒã¿ã¹ã確èªãããããã©ã³ã¶ã¯ã·ã§ã³ããã£ã³ã»ã«ãããã§ããŸãã éåæãã©ã³ã¶ã¯ã·ã§ã³ã¯ãLooperã䜿çšããã¹ã¬ããã§ã®ã¿å®è¡ãããŸãã éåæãã©ã³ã¶ã¯ã·ã§ã³ã®äŸïŒ
Realm.getDefaultInstance().use { it.executeTransactionAsync({ it.insertOrUpdate(DataObject(0)) }, { log("OnSuccess") }, { log("onError") it.printStackTrace() }) }
ããã€ãã®éèŠãªãã¥ã¢ã³ã¹ïŒ
ã»ãã¿ãŒãä»ããŠã¬ã«ã ã«é¢é£ä»ããããŠããªããªããžã§ã¯ããå²ãåœãŠãããšã¯ã§ããŸããã æåã«ãªããžã§ã¯ããããŒã¿ããŒã¹ã«é 眮ããŠãããæ·»ä»ãããã³ããŒãæ·»ä»ããå¿ èŠããããŸãã äŸïŒ
val realm = Realm.getDefaultInstance() val parent = realm.where(Parent::class.java).findFirst() val children = Children() // parent.setChildren(children) <-- Error val childrenRealm = realm.copyToRealmOrUpdate(children) parent.setChildren(childrenRealm) /// Ok
å€ãã®ãã©ã³ã¶ã¯ã·ã§ã³ã¯1ã€ã«çµåããã®ãæé©ã§ãã ã¬ã«ã ã«ã¯å éšãã©ã³ã¶ã¯ã·ã§ã³ãã¥ãŒïŒãµã€ãº100ïŒãããããããè¶ ãããšäŸå€ãã¹ããŒãããŸãã
ãã¹ãŠã®éåæãã©ã³ã¶ã¯ã·ã§ã³ã¯1ã€ã®executor'eã§åäœããŸã
// Thread pool for all async operations (Query & transaction) static final RealmThreadPoolExecutor asyncTaskExecutor = RealmThreadPoolExecutor.newDefaultExecutor();
çæéã«å€ãã®éåææäœãããå ŽåãRejectedExecutionExceptionãšã©ãŒãçºçããŸãã ãã®ç¶æ³ããæãåºãæ¹æ³ã¯ãå¥ã®ã¹ã¬ããã䜿çšããŠãã®ã¹ã¬ããã§åæãã©ã³ã¶ã¯ã·ã§ã³ãéå§ããããè€æ°ã®ãã©ã³ã¶ã¯ã·ã§ã³ã1ã€ã«çµåããããšã§ãã
ã¬ã«ã ãéã/éãã
Realmã®ç¹å®ã®ã€ã³ã¹ã¿ã³ã¹ã䜿çšããŠããŒã¿ããŒã¹ãããã¹ãŠã®ãªããžã§ã¯ããååŸãããã®ã€ã³ã¹ã¿ã³ã¹ãéããŠãããšãã«ããããæäœã§ããŸãã realm.closeïŒïŒãåŒã³åºããšããã«ããªããžã§ã¯ããèªã¿åãããšãããšäŸå€ãçºçããŸãã Realmãæéã©ããã«éããªããšãã¡ã¢ãªãªãŒã¯ãçºçããŸãã ã¬ããŒãžã³ã¬ã¯ã¿ã¯ãRealmã䜿çšãããªãœãŒã¹ã§æ£ããåäœã§ããŸããã
å ¬åŒããã¥ã¡ã³ãã§ã¯ã Realmãéãããéãããããããšããå§ãããŸãã
- ã¢ã¯ãã£ããã£ã®å ŽåïŒonCreate / onDestroy
- ãã©ã°ã¡ã³ãã®å ŽåïŒonCreateView / onDestroyView
ãã ããã¬ã«ã ãæäœããããžãã¯ãActivity \ Fragmentsãããã¬ãŒã³ã¿ãŒã«è»¢éããå Žåã¯ãã©ã€ããµã€ã¯ã«ã¡ãœãããïŒã¹ããŒïŒäœ¿çšããå¿ èŠããããŸãã
äœããã®æ¹æ³ã§ããŒã¿ãå€æŽããããæ°ããããŒã¿ãè¿œå ããå¿ èŠãããå Žåãæãç°¡åãªæ¹æ³ã¯ãæ°ããã€ã³ã¹ã¿ã³ã¹ãååŸããããŒã¿ãæžã蟌ãã§ããéããããšã§ãã Kotlinã§ã¯ããã®ããã«.useïŒïŒã䜿çšã§ããŸã
Realm.getDefaultInstance().use { // it = realm instance}
Rxã䜿çšããŠãªããžã§ã¯ããèªã¿åãã«ã¯ããåé¢ããããã€ã³ã¹ã¿ã³ã¹ã䜿çšããdoOnUnsubscribeã§ããããéããŸãïŒãŸãã¯Observable.usingã䜿çšããŸãïŒã
// Use doOnUnsubscribe val realm = Realm.getDefaultInstance() realm.where(DataObject::class.java).findAllSorted("id").asObservable().doOnUnsubscribe { realm.close() } // Use Observable.using Observable.using(Realm.getDefaultInstance(), realm -> realm.where(DataObject::class.java).equalTo("id", id) .findFirstAsync() .asObservable() .filter(realmObject -> realmObject.isLoaded()) .cast(DataObject::class.java), Realm::close);
onDestroy \ onDestroyViewã§Realmãéããããšã«é¢é£ããæ©èœããããŸãã RealmãéããåŸãFragmentManagerImpl.moveToStateâViewGroup.removeViewâ...âRecyclerViewAdapter.getItemCountïŒïŒãåŒã³åºãããç¡å¹ãªã³ã¬ã¯ã·ã§ã³ããlist.sizeïŒïŒã¡ãœãããåŒã³åºãããããšããããŸãã ãã®ãããããã§ã¯isValidïŒïŒã確èªããããrecyclerViewããã¢ããã¿ãŒã解æŸããå¿ èŠããããŸã
Kotlin Android Extensionsã䜿çšããå Žåã¯ããã¥ãŒãæäœã§ããŸãïŒkotlinx.android.syntheticããïŒãonViewCreatedïŒïŒã¡ãœããã§å§ãŸãFragmentããã®ã¿ãNPEãååŸããªãããã«ãã®ã¡ãœããã§ãã¹ãŠã®ãªã¹ããŒãæ§æããããšããå§ãããŸãã
3ã€ã®æãéèŠãªæ©èœãåæããåŸãããŸãéèŠã§ã¯ãªãæ©èœã調ã¹ãŠã¿ãŸãããã
éç¥ãRxJava
ã¬ã«ã ã¯ããªããžã§ã¯ãèªäœãšåã蟌ã¿ãªããžã§ã¯ãïŒãã¹ãŠã®ãªã³ã¯ãªããžã§ã¯ãïŒã®äž¡æ¹ã®ããŒã¿å€æŽã«é¢ããéç¥ããµããŒãããŠããŸãã ããã¯ãRealmChangeListenerïŒãªããžã§ã¯ãèªäœãä»å±ïŒãRealmObjectChangeListenerïŒå€æŽããããªããžã§ã¯ããä»å±ããã©ã®ãã£ãŒã«ããå€æŽãããããç解ã§ããŸãïŒãŸãã¯RxJavaïŒonNextã§ãªããžã§ã¯ããååŸããéåæãªã¯ãšã¹ãã®å Žåã¯isLoadedïŒïŒã確èªããå¿ èŠããããŸãïŒã䜿çšããŠå®è£ ãããŸãã«ãŒããŒãšã¹ããªãŒã ã§ïŒã
RxJava2ã¯ãŸã é ä¿¡ãããŠããŸããã 2016幎9æã«å®è£ ããããšãããåé¡ãçºçããŠããŸã-äžæã§ããInteropã䜿çšããŠãã ããã
åæ§ã«ãã³ã¬ã¯ã·ã§ã³ãŸãã¯ã€ã³ã¹ã¿ã³ã¹å šäœã®ã¬ã«ã ã®å€æŽããªãã¹ã³ã§ããŸãã ãã©ã³ã¶ã¯ã·ã§ã³å ã®å€æŽãèãããšã¯çŠæ¢ãããŠããŸãã
Rxã®äŸïŒ
fun getObjectObservable(realm: Realm, id: Long): Observable<DataObject?> { return realm.where(DataObject::class.java).equalTo("id", id).findFirstAsync() .asObservable<DataObject?>().filter({ it?.isLoaded }).filter { it?.isValid } }
ãã«ãã¹ã¬ãããšéåæ
ã¬ã«ã ã¯MVCCããŒã¿ããŒã¹ã§ãã ãŠã£ãããã£ã¢ã¯MVCCã«ã€ããŠè¿°ã¹ãŠããŸãïŒ
ãMultiVersion Concurrency ControlïŒMVCCïŒã¯ãããŒã¿ããŒã¹ãžã®äžŠåã¢ã¯ã»ã¹ãä¿èšŒããã¡ã«ããºã ã®1ã€ã§ããããã¯ãåãŠãŒã¶ãŒã«ããŒã¿ããŒã¹ã®ãããããã¹ãããã·ã§ããããæäŸããŸãããã©ã³ã¶ã¯ã·ã§ã³ãã³ãããããããŸã§ãŠãŒã¶ãŒã æžã蟌ã¿ãã©ã³ã¶ã¯ã·ã§ã³ããªãŒããŒããããã¯ãããèªã¿åããã©ã³ã¶ã¯ã·ã§ã³ãã©ã€ã¿ãŒããããã¯ããªãããã«ç®¡çãããã®æ¹æ³ã
å®éã«ã¯ã次ã®ããã«ãªããŸãããªããžã§ã¯ãã®å€æŽããªãã¹ã³ããããRxJavaã䜿çšããŠonNextã§å€æŽããããªããžã§ã¯ããååŸã§ããŸãã ã¹ããªãŒã Aã§å€æŽãçºçããã¹ããªãŒã Bã®ãªããžã§ã¯ããæäœããŠããå Žåãã¹ããªãŒã Bã¯ãã¹ããªãŒã Aã®ã¬ã«ã ã€ã³ã¹ã¿ã³ã¹ãéããåŸã®å€æŽãèªèããŸããå€æŽã¯ã«ãŒããŒãä»ããŠéä¿¡ãããŸãã ã¹ããªãŒã Bã«ã«ãŒããŒããªãå Žåãå€æŽã¯å±ããŸããïŒisAutoRefreshïŒïŒã¡ãœããã§ç¢ºèªã§ããŸãïŒã ãã®ç¶æ³ããæãåºãæ¹æ³ã¯ãwaitForChangeïŒïŒã¡ãœããã䜿çšããããšã§ãã
éåæåŒã³åºããšéåæãã©ã³ã¶ã¯ã·ã§ã³ã«ã€ããŠã¯ããŸã£ãã䜿çšããªãæ¹ãè¯ãã§ãããã ã¢ã¯ã·ã§ã³ãå¥ã®ã¹ã¬ããã«è»¢éããããã§åææäœãå®è¡ããæ¹ã䟿å©ã§ãã ããã€ãã®çç±ããããŸã ã
- éåæãã©ã³ã¶ã¯ã·ã§ã³ãšåæãã©ã³ã¶ã¯ã·ã§ã³ãæ··åšãããããšã¯ã§ããŸãããæ··åšããããšããã¹ãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ãåæãã©ã³ã¶ã¯ã·ã§ã³ã«ãªããŸã
- ã«ãŒããŒã®ãªãã¹ã¬ããã§éåæåŒã³åºãã䜿çšããããšã¯ã§ããŸãã
- é·ããã©ã³ã¶ã¯ã·ã§ã³ã®å Žåãã¬ã«ã ã®åå¥ã®ã€ã³ã¹ã¿ã³ã¹ãéãå¿ èŠããããŸããããããªããšããã©ã³ã¶ã¯ã·ã§ã³äžã«ã¬ã«ã ãéããããäŸå€ãçºçããŸãã
- éåæãã©ã³ã¶ã¯ã·ã§ã³ã®ãã¹ãŠã®ã¢ã¯ã·ã§ã³ã¯ãå¥åã®å éšãšã°ãŒãã¥ãŒã¿ãŒã§çºçããŸãããã®çµæãå€éšã¬ã«ã ãªããžã§ã¯ãã䜿çšã§ããããšã°ãŒãã¥ãŒã¿ãŒããªãŒããŒãããŒããå¯èœæ§ããããã¬ã«ã ãªããžã§ã¯ããžã®å€æŽãã¹ã¬ããéã§äŒæãããªããªã©ãäžäŸ¿ã§ãã
ãã¹ãäž
以åã¯ãRealm.javaã¯æçµçã§ããããã¹ãã«ã¯powerMockãŸãã¯ä»ã®åæ§ã®ããŒã«ãå¿ èŠã§ããã çŸæç¹ã§ã¯ãRealm.javaã¯æçµçãªãã®ã§ã¯ãªããéåžžã®mockitoãå®å šã«äœ¿çšã§ããŸãã ãã¢ãããžã§ã¯ããŸãã¯å ¬åŒãªããžããªã§ã®ãã¹ãã®äŸ
1ã€ã®ã¬ã«ã ã¯è¯ããã3ã€ã®ã¬ã«ã ã¯è¯ã
ã¬ã«ã ã䜿çšããå Žåãåžžã«æšæºã¬ã«ã ãæå³ããŸãããã€ã³ã¡ã¢ãªã¬ã«ã ãšãã€ãããã¯ã¬ã«ã ããŸã ãããŸãã
æšæºã¬ã«ã -Realm.getDefaultInstanceïŒïŒã¡ãœãããŸãã¯ç¹å®ã®Realm.getInstanceïŒconfigïŒæ§æã䜿çšããŠååŸã§ããŸããæ§æã®æ°ã«å¶éã¯ãããŸããããããã¯æ¬è³ªçã«å¥åã®ããŒã¿ããŒã¹ã§ãã
ã€ã³ã¡ã¢ãªã¬ã«ã ã¯ãèšé²ããããã¹ãŠã®ããŒã¿ããã£ã¹ã¯ã«æžã蟌ãŸãã«ã¡ã¢ãªã«ä¿åããã¬ã«ã ã§ãã ãã®ã€ã³ã¹ã¿ã³ã¹ãéãããšããã«ããã¹ãŠã®ããŒã¿ã倱ãããŸãã çæã®ããŒã¿ã¹ãã¬ãŒãžã«é©ããŠããŸãã
åçã¬ã«ã -äž»ã«ç§»è¡äžã«äœ¿çšãããã¬ã«ã ãæäœã§ããŸã-çæãããRealmObjectã¯ã©ã¹ã䜿çšããã«ãªããžã§ã¯ãããã£ãŒã«ãåã«ãã£ãŠã¢ã¯ã»ã¹ãå®è¡ãããŸãã
ç¶æ¿ãšå€å
ã¬ã«ã ã¯ç¶æ¿ããµããŒãããŠããŸããã ã¬ã«ã ãªããžã§ã¯ãã¯ãRealmObjectãç¶æ¿ããããRealmModelããŒã«ãŒã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ãã@ RealmClassã¢ãããŒã·ã§ã³ã§ã¿ã°ä»ãããå¿ èŠããããŸãã æ¢åã®ã¬ã«ã ãªããžã§ã¯ãããç¶æ¿ããããšã¯ã§ããŸããã ç¶æ¿ã®ä»£ããã«æ§æã䜿çšããããšããå§ãããŸãã éåžžã«æ·±å»ãªåé¡ã§ã åé¡ã¯2015幎1æããç¶ããŠããŸããããŸã åé¡ã¯æ®ã£ãŠããŸãã
ã³ããªã³
ããã«äœ¿çšã§ããã¬ã«ã ã¯ã Kotlinã§åäœããŸãã
ããŒã¿ã¯ã©ã¹ã¯æ©èœããŸãããéåžžã®ãªãŒãã³ã¯ã©ã¹ã䜿çšããå¿ èŠããããŸãã
ãŸãã泚ç®ã«å€ããã®ã¯Kotlin-Realm-Extensionsã§ããããã¯ãRealmObjectãæäœããããã®äŸ¿å©ãªæ¡åŒµæ©èœã§ãã
ã¬ã«ã ã¢ãã€ã«ãã©ãããã©ãŒã
åœåãã¬ã«ã ã¯ç°ãªããã©ãããã©ãŒã ã®ããŒã¿ããŒã¹ã®ã¿ã§è¡šãããŠããŸããããçŸåšã§ã¯ãã¹ãŠã®ããã€ã¹éã®åæã®ããã«ãµãŒããŒãå±éããŠããŸãã çŸåšããã©ãããã©ãŒã ã¯æ¬¡ã®ãã®ã§æ§æãããŠããŸãã
- Realm Mobile Database-ããŒã¿ãä¿åããããã®ããŒã¿ããŒã¹
- Realm Object Server-èªååæãšã€ãã³ãåŠçãæ åœãããµãŒããŒ
- Realm Data Integration API-æ¢åã®ããŒã¿ããŒã¹ïŒOracleãMongoDBãHadoopãSAP HANAãPostgresãRedisïŒãšã®ããŒã¿ã®æ¥ç¶ããã³åæçš
ã¢ãã€ã«ãã©ãããã©ãŒã ã®å³
ãããã°
ãããã°çšã«ãããã€ãã®ããŒã«ããããŸãã
- RealmLog-ãã°ã衚瀺ããŸããããŸããŸãªã¬ãã«ã®ãã°ããããŸã
- ã¬ã«ã ãã©ãŠã¶ãŒ -ã³ã³ãã¥ãŒã¿ãŒããããŒã¿ããŒã¹ã衚瀺ããå¿
èŠããããŸãã Macã§ã®ã¿åäœããŸãã Windowsã®ããŒã¹ã衚瀺ããã«ã¯ã Stetho Realmã䜿çšã§ããŸã
Android .
- WriteCopyTo() â .
- NDK Debugging â Crashlytics NDK Crash Reporting
建ç¯
Realmã¯ãå®è£ å šäœãããŒã¿ããŒã¹ã€ã³ã¿ãŒãã§ã€ã¹ã®èåŸã«é ããŠããå ŽåãMV *ã¢ãŒããã¯ãã£ã«æé©ã§ãããã¹ãŠã®åŒã³åºããšéžæã¯ããŒã¿ããŒã¹ã¢ãžã¥ãŒã«ïŒãªããžããªïŒã§è¡ãããObservable cã¯ããµãã¹ã¯ã©ã€ã解é€æã«èªåçã«éããããã¬ã«ã ã§èªåçã«ãããã«æ»ããŸãããŸãã¯ãå ¥åã§ã€ã³ã¹ã¿ã³ã¹ã¬ã«ã ãåãå ¥ããããã䜿çšããŠãã¹ãŠã®ã¢ã¯ã·ã§ã³ãå®è¡ããŸãããªããžã§ã¯ããèšé²ãããšããã¬ã«ã ãéããããŒã¿ãæžã蟌ãã§éããŸããä¿åãããªããžã§ã¯ãã®ã¿ãå ¥åãããŸããäž¡æ¹ã®äŸã¯githubã«ãããŸãã
æ²ããããªãRealmïŒcopyFromRealmãªãïŒã䜿çšãããšãã¯ãªãŒã³ã¢ãŒããã¯ãã£ã®äœ¿çšã«é倧ãªå¶éã課ããããŸããã¬ã€ã€ãŒããšã«ç°ãªãããŒã¿ã¢ãã«ã䜿çšããããšã¯ã§ããŸãããã©ã€ããªããžã§ã¯ããšãããã·ãªã¹ãã®ãã€ã³ãããã¹ãŠæ¶ããŸãããŸããç¬ç«ããã¬ã€ã€ãŒãäœæããã¬ã«ã ãéãããéããããããšããã®æäœãã¢ã¯ãã£ããã£\ãã©ã°ã¡ã³ãã©ã€ããµã€ã¯ã«ã«é¢é£ä»ãããããããå°é£ãçããŸããé©åãªãªãã·ã§ã³ã¯ããªããžã§ã¯ããå€æããããŒã¿ããŒã¹ã«ä¿åããåé¢ãããããŒã¿ååŸã¬ã€ã€ãŒã§ãã
ã¬ã«ã ã¯ãããŒã¿ããŒã¹ãã衚瀺ãããã¹ãŠã®ããŒã¿ãååŸãããªãã©ã€ã³ãã¡ãŒã¹ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå Žåã«éåžžã«äŸ¿å©ã§ãã
䟿å©ãªãªã³ã¯
ïŒé£çµ¡å ãç¶ç¶ãã现ããç¹ã解æããããã«ãæã ã¯ã以äžã®èšäºããå§ãããŸã
èšäºããã®3ã€ã®èšäº@ZhuindenïŒ
ã¬ã«ã ã®åºæ¬ïŒã¬ã«ã 1.2.0䜿çšãžã®ã¬ã€ã
ãã£ã³ããªã³ã®ããã«å šãŠã®Androidçšã®ã¬ã«ã ã䜿çšããæ¹æ³ããã©ã®ããã«ããªãããã£ãŠããå Žåã®äŒããããã«ééã£ãITã®
ã¬ã«ã ãã¹ãŠã®ã¢ã³ããã€ã1.2.0 +ããŒã¿ãã€ã³ãã£ã³ã°
ã¬ã«ã ã®çµ±åã«ã€ããŠ2件ã®èšäºViraj.Tank @
ã»ãŒãã³ãŒãã®äžãçç£ã®ãã¹ãŠã®Androidã¬ã«ã ã®çµ±åããšããŒã1-MVP
MVPãšã®ã³ãŒãã®äžã«çç£ã®ã¬ã«ã ã®ãã¹ãŠã®Androidã®æ·±ãçµ±åãããŒã2ã
ãã«ãã¹ã¬ããã詳现åæïŒ
ããŒã¿ããŒã¹ã®èšèšïŒã¬ã«ã ã¹ã¬ãããã£ãŒããã€ã
ããã¥ã¡ã³ã-èªåæŽæ°
ããã¥ã¡ã³ã-ã¹ã¬ãã
FairBearã®Haberã«é¢ããæè¿ã®èšäºïŒ
ã¬ã«ã ãšåéã«ãªãæ¹æ³
ãããã«
ã¬ã«ã ã¯ãäžèŠæããããããè€éã§ãããã ãããã¹ãŠã®æ¬ ç¹ã¯ããã®ãã¯ãŒãšå©äŸ¿æ§ã«ãã£ãŠã«ããŒãããŠããŸããã©ã€ããªããžã§ã¯ããéç¥ãRxã䟿å©ãªAPIãªã©ãããŸããŸãªãã®ãã¢ããªã±ãŒã·ã§ã³ã®äœæãç°¡çŽ åããŸãã競åä»ç€Ÿã«ã¯ãåã¯ãšãªãObjectBoxãGreenDaoããããŸããã¬ã«ã ã¯ããªãã©ã€ã³ãã¡ãŒã¹ãã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ãããšãããã£ãã·ã¥ãããã¹ãŠã®ããŒã¿ãååŸããè€éãªãµã³ãã«ãšããŒã¿ã®çµ¶ãéãªãæŽæ°ãå¿ èŠãªãšãã«å®å šã«æããã«ãªããŸããGithubã«ãã
ãã¹ãŠã®ã³ãŒã