Dodo Pizzaã¢ããªã±ãŒã·ã§ã³ãå¹³å3ç§ã§éå§ããããšãããã£ãããäžéšã®ã幞éãªãã®ãã®å Žåã¯15ã20ç§ããããŸãã
ã«ããã®äžã«ã¯ãããããŒãšã³ãã®ã¹ããŒãªãŒããããŸããã¬ã«ã ããŒã¿ããŒã¹ã®æé·ãã¡ã¢ãªãªãŒã¯ããã¹ãããããªããžã§ã¯ãã®ä¿åæ¹æ³ããããŠãã¹ãŠããŸãšããŠä¿®æ£ããæ¹æ³ã«ã€ããŠã§ãã
![]()
èšäºã®èè ïŒMaxim Kachinkinã¯ãDodoPizzaã®Androidéçºè ã§ãã
ã¢ããªã±ãŒã·ã§ã³ã¢ã€ã³ã³ãã¯ãªãã¯ããŠããæåã®ã¢ã¯ãã£ããã£ã®onResumeïŒïŒãŸã§ã®3ç§ã¯ç¡é倧ã§ãããŸããäžéšã®ãŠãŒã¶ãŒã®å Žåãèµ·åæéã¯15ã20ç§ã«éããŸãããããã¯ã©ãããŠå¯èœã§ããïŒ
èªãæéããªã人ã®ããã®éåžžã«çãèŠçŽ
Realm. , . . , â 1 . â - -.
åé¡ã®æ€çŽ¢ãšåæ
仿¥ãã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ã¯ãè¿ éã«èµ·åããå¿çããå¿ èŠããããŸããããããããã¯ã¢ãã€ã«ã¢ããªã ãã§ã¯ãããŸããããµãŒãã¹ãäŒç€ŸãšããåããããŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã¯è€éã§ããããšãã°ãç§ãã¡ã®å Žåãé éé床ã¯ãã¶ãµãŒãã¹ã®éèŠãªææšã®1ã€ã§ããé éãéããã°ããã¶ã¯ç±ããªããä»é£ã¹ãã顧客ã¯é·ãåŸ ã€å¿ èŠã¯ãããŸãããã¢ããªã±ãŒã·ã§ã³ã®å Žåãã¢ããªã±ãŒã·ã§ã³ã20ç§ããéå§ããªãå Žåããã¶ã«ã©ããããã®æéããããã®ã§ãé«éãµãŒãã¹ã®æèŠãäœãåºãããšãéèŠã§ãã
æåã¯ãã¢ããªã±ãŒã·ã§ã³ãæ°ç§éèµ·åãããããšããããšããäºå®ã«çŽé¢ããŸãããããã®åŸãä»ã®ååãããé·ãããšããèŠæ ãå¯ãããå§ããŸããããããããã®ç¶æ³ãå®å®ããŠç¹°ãè¿ãããšã¯ã§ããŸããã§ããã
ããã¯ã©ã®ãããé·ãã§ããïŒã«ããGoogleã®ããã¥ã¡ã³ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒã«ãã¹ã¿ãŒãã«5ç§ãããããªãå Žåããéåžžã®çš®é¡ããšèŠãªãããŸãã Dodo Pizza Androidã¢ããªã±ãŒã·ã§ã³ã¯ïŒFirebase _app_startã¡ããªãã¯ã«ãããšïŒã³ãŒã«ãã¹ã¿ãŒãã§å¹³å3ç§ã§èµ·åãããŸãã-圌ããèšãããã«ããè¯ããªããã²ã©ããã
ãããããã®åŸãã¢ããªã±ãŒã·ã§ã³ãéåžžã«ãéåžžã«ãéåžžã«é·ãéèµ·åããããšããèŠæ ãçŸãå§ããŸããïŒãŸãããéåžžã«ãéåžžã«ãéåžžã«é·ãããã®ã枬å®ããããšã«ããŸããããããŠãããã«ã¯Firebase trace App starttraceã䜿çšããŸããã
ãã®æšæºãã¬ãŒã¹ã¯ããŠãŒã¶ãŒãã¢ããªã±ãŒã·ã§ã³ãéããŠããæåã®ã¢ã¯ãã£ããŒã·ã§ã³ã®onResumeïŒïŒãå®è¡ããããŸã§ã®æéãæž¬å®ããŸãã Firebase Consoleã§ã¯ããã®ã¡ããªãã¯ã¯_app_startãšåŒã°ããŸããããã¯æããã«ãªã£ãïŒ
- ã³ãŒã«ãã¹ã¿ãŒãæéã®äžå€®å€ã5ç§æªæºã§ããã«ããããããã95ããŒã»ã³ã¿ã€ã«ãè¶ ãããŠãŒã¶ãŒã®èµ·åæéã¯ã»ãŒ20ç§ã§ãïŒäžéšã®ãŠãŒã¶ãŒã¯ãã以äžã§ãïŒã
- èµ·åæéã¯äžå®ã§ã¯ãããŸããããæéã®çµéãšãšãã«å¢å ããŸããããããæã 転åã芳å¯ãããŸããåæã¹ã±ãŒã«ã90æ¥ã«å¢ããããšãã«ããã®ãã¿ãŒã³ãèŠã€ãããŸããã
2ã€ã®èããæãæµ®ãã³ãŸããã
- äœããæŒããŠããŸãã
- ãã®ãäœããã¯ãªãªãŒã¹åŸã«ç Žæ£ããããã®åŸåã³ãªãŒã¯ãããŸãã
ãããããããŒã¿ããŒã¹ã®äœãããšç§ãã¡ã¯èããæ£ããã£ãããŸããããŒã¿ããŒã¹ããã£ãã·ã¥ãšããŠäœ¿çšããç§»è¡äžã«ã¯ãªã¢ããŸããæ¬¡ã«ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã«ããŒã¿ããŒã¹ãããŒããããŸããããã¯ãã¹ãŠäžç·ã«åãŸããŸãã
ã¬ã«ã ããŒã¿ããŒã¹ã®äœãåé¡ã«ãªã£ãŠããŸãã
æåã®ã€ã³ã¹ããŒã«ããããã«ã¢ã¯ãã£ããªäœ¿çšã®éçšã§ãã¢ããªã±ãŒã·ã§ã³ã®åç¶æéäžã«ããŒã¿ããŒã¹ã®ã³ã³ãã³ããã©ã®ããã«å€åãããã確èªãå§ããŸãããããªãã¯ãéããŠã¬ã«ã ããŒã¿ããŒã¹ã®å 容ã衚瀺ããããšãã§ãStethoãŠãã¡ã€ã«ãéããããã詳现ã«ãã€èŠèŠçã«ã¬ã«ã ã¡ãŒã«ãŒãADBãä»ããŠããŒã¿ããŒã¹ã®å 容ã衚瀺ããã«ã¯ãã¬ã«ã ããŒã¿ããŒã¹ãã¡ã€ã«ãã³ããŒããŸãã
adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}
ããŸããŸãªæç¹ã§ããŒã¿ããŒã¹ã®å 容ã調ã¹ããšãããç¹å®ã®ã¿ã€ãã®ãªããžã§ã¯ãã®æ°ãçµ¶ããå¢å ããŠããããšãããããŸããã

åçã¯ã2ã€ã®ãã¡ã€ã«ã®Realm Studioã®ãã©ã°ã¡ã³ãã瀺ããŠããŸããå·ŠåŽ-ã€ã³ã¹ããŒã«åŸãã°ããããŠããã®ã¢ããªã±ãŒã·ã§ã³ããŒã¿ããŒã¹ãå³åŽ-ã¢ã¯ãã£ãã«äœ¿çšããåŸããªããžã§ã¯ãã®æ°ããšãåãã
ImageEntityãšã¯ãMoneyTypeïŒã¹ã¯ãªãŒã³ã·ã§ããã¯ãåã¿ã€ãã®ãªããžã§ã¯ãã®æ°ã瀺ãïŒã倧ããæé·ããŠããŸãã
ããŒã¿ããŒã¹ã®æé·ãšèµ·åæéã®é¢ä¿
å¶åŸ¡ãããŠããªãããŒã¿ããŒã¹ã®å¢å ã¯éåžžã«æªãã§ããããããããã¯ã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéã«ã©ã®ããã«åœ±é¿ããŸããïŒActivityManagerã䜿çšããŠæž¬å®ããã®ã¯éåžžã«ç°¡åã§ããAndroid 4.4以éãlogcatã¯è¡šç€ºãããæååãšæå»ã§ãã°ã衚瀺ããŸãããã®æéã¯ãã¢ããªã±ãŒã·ã§ã³ã®éå§ããã¢ã¯ãã£ããã£ã®ã¬ã³ããªã³ã°ã®çµäºãŸã§ã®ééã«çãããªããŸãããã®éãã€ãã³ããçºçããŸãã
- ããã»ã¹ãéå§ããŸãã
- ãªããžã§ã¯ãã®åæåã
- ã¢ã¯ãã£ããã£ã®äœæãšåæåã
- ã¬ã€ã¢ãŠãã®äœæã
- ã¢ããªã±ãŒã·ã§ã³ã®ã¬ã³ããªã³ã°ã
ç§ãã¡ã«é©ããŠããŸãã-Sãã©ã°ãš-Wãã©ã°ãæå®ããŠADBãå®è¡ãããšãéå§æå»ãæå®ããŠæ¡åŒµåºåãååŸã§ããŸãã
adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN
ãããã
grep -i WaitTimeæéãåéãããšããã®ã¡ããªãã¯ã®åéãèªååããŠãçµæãã°ã©ãã£ã«ã«ã«ç¢ºèªã§ããŸãã以äžã®ã°ã©ãã¯ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéã®ã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒã«ãã¹ã¿ãŒãæ°ãžã®äŸåæ§ã瀺ããŠããŸãã
åæã«ãããŒã¹ã®ãµã€ãºãšæé·ã®äŸåæ§ã¯åãã§ã4MBãã15MBã«å¢å ããŸãããå šäœãšããŠãæéã®çµéãšãšãã«ïŒã³ãŒã«ãã¹ã¿ãŒãã®å¢å ã«äŒŽãïŒãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéãšããŒã¿ããŒã¹ã®ãµã€ãºã®äž¡æ¹ãå¢å ããããšãããããŸãããç§ãã¡ã®æã«ã¯ä»®èª¬ããããŸããä»ã§ã¯äŸåé¢ä¿ã確èªããããã«æ®ã£ãããã®ãããããªãŒã¯ããåé€ããŠãèµ·åãé«éåããããã©ããã確èªããããšã«ããŸããã
ããŒã¿ããŒã¹ã®ç¡éã®æé·ã®çç±
ããªãŒã¯ããåãé€ãåã«ããªããããããŸã£ããçŸããã®ããçè§£ãã䟡å€ããããŸãããããè¡ãããã«ãã¬ã«ã ãäœã§ããããèŠããŠãããŸãããã
ã¬ã«ã ã¯éãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã§ããããã«ãããAndroidäžã®å€ãã®ORMãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã説æããã®ãšåæ§ã®æ¹æ³ã§ããªããžã§ã¯ãéã®é¢ä¿ã説æã§ããŸããåæã«ãã¬ã«ã ã¯ã倿ãšãããã³ã°ã®æ°ãæå°éã«æããŠããªããžã§ã¯ããã¡ã¢ãªã«çŽæ¥ä¿åããŸããããã«ããããã£ã¹ã¯ããããŒã¿ãéåžžã«ãã°ããèªã¿åãããšãã§ããŸããããã¯ãã¬ã«ã ã®åŒ·ã¿ã§ãããæãããŠããŸãã
ïŒãã®èšäºã®ç®çã®ããã«ããã®èª¬æã¯ç§ãã¡ã«ãšã£ãŠååã§ããããªãã¯ã¯ãŒã«ãªããã¥ã¡ã³ããŸãã¯åœŒãã®ã¢ã«ãããŒã§ã¬ã«ã ã«ã€ããŠãã£ãšèªãããšãã§ããŸãïŒã
å€ãã®éçºè ã¯ããªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ïŒããšãã°ãå éšã§SQLã䜿çšããORMããŒã¿ããŒã¹ïŒãããå€ã䜿çšããããšã«æ £ããŠããŸãããŸããã«ã¹ã±ãŒãããŒã¿ã®åé€ãªã©ã¯åœç¶ã®ããšã®ããã«æãããããšããããããŸããããããã¬ã«ã ã§ã¯ãããŸããã
ã¡ãªã¿ã«ãã«ã¹ã±ãŒãå逿©èœã¯é·ãéæ±ããããŠããŸããããã®æ¹èšãšããã«é¢é£ããå¥ã®æ¹èšã掻çºã«è°è«ãããŸãããããããããæ°ãããŸããããããããã®åŸããã¹ãŠã匷ããªã³ã¯ãšåŒ±ããªã³ã¯ã®å°å ¥ã«å€ãããããããã®åé¡ãèªåçã«è§£æ±ºããŸãããã®ã¿ã¹ã¯ã§ã¯ãããªã掻çºã§ã¢ã¯ãã£ããªãã«ãªã¯ãšã¹ãããããŸããããå éšã®åé¡ã®ããã«äžæåæ¢ãããŸããã
ã«ã¹ã±ãŒãåé€ãªãã®ããŒã¿ãªãŒã¯
ååšããªãã«ã¹ã±ãŒãåé€ãåžæããå ŽåãããŒã¿ã¯ã©ã®çšåºŠæ£ç¢ºã«ãªãŒã¯ããŸããïŒ Realmãªããžã§ã¯ãããã¹ãããŠããå Žåã¯ãããããåé€ããå¿ èŠããããŸãã
ïŒã»ãŒïŒå®éã®äŸãèŠãŠã¿ãŸãããããªããžã§ã¯ãããããŸã
CartItemEntityïŒ
@RealmClass
class CartItemEntity(
@PrimaryKey
override var id: String? = null,
...
var name: String = "",
var description: String = "",
var image: ImageEntity? = null,
var category: String = MENU_CATEGORY_UNKNOWN_ID,
var customizationEntity: CustomizationEntity? = null,
var cartComboProducts: RealmList<CartProductEntity> = RealmList(),
...
) : RealmObject()
ã«ãŒãå ã®è£œåã«ã¯ãåç
ImageEntityãã«ã¹ã¿ãã€ãºãããææãªã©ãããŸããŸãªãã£ãŒã«ãããããŸãCustomizationEntityããŸãããã¹ã±ããå
ã®è£œåã¯ãç¬èªã®è£œåã»ãããšçµã¿åãããããšãã§ããŸãRealmList (CartProductEntity)ããªã¹ããããŠãããã£ãŒã«ãã¯ãã¹ãŠã¬ã«ã ãªããžã§ã¯ãã§ããåãIDã®æ°ãããªããžã§ã¯ãïŒcopyToRealmïŒïŒ/ copyToRealmOrUpdateïŒïŒïŒãæ¿å
¥ãããšããã®ãªããžã§ã¯ãã¯å®å
šã«äžæžããããŸãããã ãããã¹ãŠã®å
éšãªããžã§ã¯ãïŒimageãcustomizationEntityãcartComboProductsïŒã¯èŠªãšã®æ¥ç¶ã倱ããããŒã¿ããŒã¹ã«æ®ããŸãã
ããããšã®æ¥ç¶ã倱ããããããããããèªã¿åã£ããåé€ãããããããšã¯ãããŸããïŒæç€ºçã«åç §ãããããããŒãã«ãå šäœãã¯ãªã¢ããªãéãïŒãããããã¡ã¢ãªãªãŒã¯ããšåŒã³ãŸããã
Realmã䜿çšããå Žåããã®ãããªæäœã®åã«ããã¹ãŠã®èŠçŽ ãæç€ºçã«èª¿ã¹ããã¹ãŠãæç€ºçã«åé€ããå¿ èŠããããŸããããã¯ãããšãã°ã次ã®ããã«å®è¡ã§ããŸãã
val entity = realm.where(CartItemEntity::class.java).equalTo("id", id).findFirst()
if (first != null) {
deleteFromRealm(first.image)
deleteFromRealm(first.customizationEntity)
for(cartProductEntity in first.cartComboProducts) {
deleteFromRealm(cartProductEntity)
}
first.deleteFromRealm()
}
//
ãããè¡ããšããã¹ãŠãæ£åžžã«æ©èœããŸãããã®äŸã§ã¯ãimageãcustomizationEntityãããã³cartComboProductså ã«ä»ã®ãã¹ããããã¬ã«ã ããªãããšãåæãšããŠãããããä»ã®ãã¹ããããã«ãŒããåé€ã¯ãããŸããã
ã¯ã€ãã¯ãœãªã¥ãŒã·ã§ã³
ãŸããæãæé·ã®éããªããžã§ã¯ããã¯ãªãŒã³ã¢ããããŠçµæã確èªããããšã«ããŸãããããã§å ã®åé¡ã解決ãããã©ããã確èªããŸããæåã«ãæãåçŽã§çŽæçãªè§£æ±ºçãäœæãããŸãããã€ãŸããåãªããžã§ã¯ãã¯ãããèªäœã®åŸã«åãåé€ãã責任ããããŸãããããè¡ãããã«ããã¹ããããRealmãªããžã§ã¯ãã®ãªã¹ããè¿ã次ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå°å ¥ããŸããã
interface NestedEntityAware {
fun getNestedEntities(): Collection<RealmObject?>
}
ãããŠããããã¬ã«ã ãªããžã§ã¯ãã«å®è£ ããŸããã
@RealmClass
class DataPizzeriaEntity(
@PrimaryKey
var id: String? = null,
var name: String? = null,
var coordinates: CoordinatesEntity? = null,
var deliverySchedule: ScheduleEntity? = null,
var restaurantSchedule: ScheduleEntity? = null,
...
) : RealmObject(), NestedEntityAware {
override fun getNestedEntities(): Collection<RealmObject?> {
return listOf(
coordinates,
deliverySchedule,
restaurantSchedule
)
}
}
getNestedEntitiesæã
ã¯ããã¹ãŠã®åäŸãã¡ã«ãã©ãããªãªã¹ããè¿ããŸãããŸããååãªããžã§ã¯ãã¯NestedEntityAwareã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããŠãåé€ããå
éšRealmãªããžã§ã¯ããããããšãéç¥ã§ããŸããæ¬¡ã«äŸã瀺ãScheduleEntityãŸãã
@RealmClass
class ScheduleEntity(
var monday: DayOfWeekEntity? = null,
var tuesday: DayOfWeekEntity? = null,
var wednesday: DayOfWeekEntity? = null,
var thursday: DayOfWeekEntity? = null,
var friday: DayOfWeekEntity? = null,
var saturday: DayOfWeekEntity? = null,
var sunday: DayOfWeekEntity? = null
) : RealmObject(), NestedEntityAware {
override fun getNestedEntities(): Collection<RealmObject?> {
return listOf(
monday, tuesday, wednesday, thursday, friday, saturday, sunday
)
}
}
ãªã©ããªããžã§ã¯ãã®ãã¹ããç¹°ãè¿ãããšãã§ããŸãã
次ã«ããã¹ãããããã¹ãŠã®ãªããžã§ã¯ããååž°çã«åé€ããã¡ãœãããèšè¿°ããŸãããã®ã¡ãœããïŒæ¡åŒµæ©èœã®åœ¢åŒã§äœæïŒ
deleteAllNestedEntitiesã¯ããã¹ãŠã®ãããã¬ãã«ãªããžã§ã¯ããååŸdeleteNestedRecursivelyããNestedEntityAwareã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠãã¹ãããããã¹ãŠã®ãã®ãååž°çã«åé€ããŸãã
fun <T> Realm.deleteAllNestedEntities(entities: Collection<T>,
entityClass: Class<out RealmObject>,
idMapper: (T) -> String,
idFieldName : String = "id"
) {
val existedObjects = where(entityClass)
.`in`(idFieldName, entities.map(idMapper).toTypedArray())
.findAll()
deleteNestedRecursively(existedObjects)
}
private fun Realm.deleteNestedRecursively(entities: Collection<RealmObject?>) {
for(entity in entities) {
entity?.let { realmObject ->
if (realmObject is NestedEntityAware) {
deleteNestedRecursively((realmObject as NestedEntityAware).getNestedEntities())
}
realmObject.deleteFromRealm()
}
}
}
æãæé·ã®éããªããžã§ã¯ãã§ãããè¡ããäœãèµ·ãã£ããã確èªããŸããã
ãã®çµæããã®ãœãªã¥ãŒã·ã§ã³ã§ã«ããŒãããªããžã§ã¯ãã¯æé·ã忢ããŸããããããŠãåºå°ã®å šäœçãªæé·ã¯éåããŸããããæ¢ãŸããŸããã§ããã
ãéåžžã®ããœãªã¥ãŒã·ã§ã³
ããŒã¹ã¯ãã£ãããšæé·ãå§ããŸããããããã§ãæé·ããŠããŸãããããã§ç§ãã¡ã¯ããã«èª¿ã¹å§ããŸãããç§ãã¡ã®ãããžã§ã¯ãã§ã¯ãã¬ã«ã ã®ããŒã¿ãã£ãã·ã³ã°ãéåžžã«ç©æ¥µçã«äœ¿çšãããŠããŸãããããã£ãŠãåãªããžã§ã¯ãã«ãã¹ãããããã¹ãŠã®ãªããžã§ã¯ããæžã蟌ãã®ã¯é¢åã§ãããã³ãŒãã倿Žãããšãã«ãªããžã§ã¯ããæå®ããã®ãå¿ããããšãã§ããããããšã©ãŒã®ãªã¹ã¯ãé«ãŸããŸãã
ã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããã®ã§ã¯ãªãããã¹ãŠãåç¬ã§æ©èœããããã«ãããã£ãã®ã§ãã
äœããåç¬ã§æ©èœããããå Žåã¯ããªãã¬ã¯ã·ã§ã³ã䜿çšããå¿ èŠããããŸãããããè¡ãã«ã¯ãã¯ã©ã¹ã®åãã£ãŒã«ãã調ã¹ãŠããããRealmãªããžã§ã¯ãã§ããããªããžã§ã¯ãã®ãªã¹ãã§ãããã確èªããŸãã
RealmModel::class.java.isAssignableFrom(field.type)
RealmList::class.java.isAssignableFrom(field.type)
ãã£ãŒã«ããRealmModelãŸãã¯RealmListã®å Žåããã®ãã£ãŒã«ãã®ãªããžã§ã¯ãããã¹ãããããªããžã§ã¯ãã®ãªã¹ãã«è¿œå ããŸãããã¹ãŠãäžã§è¡ã£ãã®ãšãŸã£ããåãã§ãããããã§ã®ã¿ãããåç¬ã§è¡ãããŸããã«ã¹ã±ãŒãåé€ã¡ãœããèªäœã¯éåžžã«åçŽã§ã次ã®ããã«ãªããŸãã
fun <T : Any> Realm.cascadeDelete(entities: Collection<T?>) {
if(entities.isEmpty()) {
return
}
entities.filterNotNull().let { notNullEntities ->
notNullEntities
.filterRealmObject()
.flatMap { realmObject -> getNestedRealmObjects(realmObject) }
.also { realmObjects -> cascadeDelete(realmObjects) }
notNullEntities
.forEach { entity ->
if((entity is RealmObject) && entity.isValid) {
entity.deleteFromRealm()
}
}
}
}
æ¡åŒµæ©èœ
filterRealmObjectã¯ãã¬ã«ã ãªããžã§ã¯ãã®ã¿ããã£ã«ã¿ãªã³ã°ããŠæž¡ããŸãããã®ã¡ãœããgetNestedRealmObjectsã¯ããªãã¬ã¯ã·ã§ã³ã«ãã£ãŠãã¹ãããããã¹ãŠã®Realmãªããžã§ã¯ããæ€çŽ¢ããããããç·åœ¢ãªã¹ãã«è¿œå ããŸããæ¬¡ã«ãåãããšãååž°çã«è¡ããŸããåé€ãããšãã¯ããªããžã§ã¯ãã®æå¹æ§ã確èªããå¿
èŠãããisValidãŸããããã¯ãç°ãªã芪ãªããžã§ã¯ããåããã¹ãããããªããžã§ã¯ããæã£ãŠããå¯èœæ§ãããããã§ãããããåé¿ããæ°ãããªããžã§ã¯ããäœæãããšãã¯idèªåçæã䜿çšããããšããå§ãããŸãã

getNestedRealmObjectsã¡ãœããã®å®å
šãªå®è£
private fun getNestedRealmObjects(realmObject: RealmObject) : List<RealmObject> {
val nestedObjects = mutableListOf<RealmObject>()
val fields = realmObject.javaClass.superclass.declaredFields
// , RealmModel RealmList
fields.forEach { field ->
when {
RealmModel::class.java.isAssignableFrom(field.type) -> {
try {
val child = getChildObjectByField(realmObject, field)
child?.let {
if (isInstanceOfRealmObject(it)) {
nestedObjects.add(child as RealmObject)
}
}
} catch (e: Exception) { ... }
}
RealmList::class.java.isAssignableFrom(field.type) -> {
try {
val childList = getChildObjectByField(realmObject, field)
childList?.let { list ->
(list as RealmList<*>).forEach {
if (isInstanceOfRealmObject(it)) {
nestedObjects.add(it as RealmObject)
}
}
}
} catch (e: Exception) { ... }
}
}
}
return nestedObjects
}
private fun getChildObjectByField(realmObject: RealmObject, field: Field): Any? {
val methodName = "get${field.name.capitalize()}"
val method = realmObject.javaClass.getMethod(methodName)
return method.invoke(realmObject)
}
ãã®çµæãã¯ã©ã€ã¢ã³ãã³ãŒãã§ã¯ããã¹ãŠã®ããŒã¿å€æŽæäœã«ãã«ã¹ã±ãŒãåé€ãã䜿çšããŸããããšãã°ãæ¿å ¥æäœã®å Žåãæ¬¡ã®ããã«ãªããŸãã
override fun <T : Entity> insert(
entityInformation: EntityInformation,
entities: Collection<T>): Collection<T> = entities.apply {
realmInstance.cascadeDelete(getManagedEntities(entityInformation, this))
realmInstance.copyFromRealm(
realmInstance
.copyToRealmOrUpdate(this.map { entity -> entity as RealmModel }
))
}
æåã«ãã¡ãœãã
getManagedEntitiesã¯è¿œå ããããã¹ãŠã®ãªããžã§ã¯ããååŸããæ¬¡ã«ã¡ãœããcascadeDeleteã¯æ°ãããªããžã§ã¯ããæžã蟌ãåã«ãåéããããã¹ãŠã®ãªããžã§ã¯ããååž°çã«åé€ããŸããæçµçã«ãã¢ããªã±ãŒã·ã§ã³å
šäœã§ãã®ã¢ãããŒãã䜿çšããããšã«ãªããŸããã¬ã«ã ã®ã¡ã¢ãªãªãŒã¯ã¯å®å
šã«ãªããªããŸãããã¢ããªã±ãŒã·ã§ã³ã®ã³ãŒã«ãã¹ã¿ãŒãæ°ã«å¯Ÿããèµ·åæéã®äŸåæ§ã«ã€ããŠåãæž¬å®ãå®è¡ãããšãçµæã衚瀺ãããŸãã
ç·ã®ç·ã¯ããã¹ãããããªããžã§ã¯ãã®èªåã«ã¹ã±ãŒãåé€äžã®ã³ãŒã«ãã¹ã¿ãŒãã®æ°ã«å¯Ÿããã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéã®äŸåæ§ã瀺ããŠããŸãã
çµæãšçµè«
å¢ãç¶ããã¬ã«ã ããŒã¿ããŒã¹ã¯ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åãå€§å¹ ã«é ãããŸããããã¹ãããããªããžã§ã¯ãã®ç¬èªã®ãã«ã¹ã±ãŒãåé€ããåããã¢ããããŒãããªãªãŒã¹ããŸããããããŠä»ãç§ãã¡ã¯_app_startã¡ããªãã¯ãéããŠãç§ãã¡ã®æ±ºå®ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéã«ã©ã®ããã«åœ±é¿ãããã远跡ããã³è©äŸ¡ããŸãã
åæã®ããã«ã90æ¥ã®æéééãåããæ¬¡ã®ããšã確èªããŸããã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéã®äžå€®å€ãšãŠãŒã¶ãŒã®95ããŒã»ã³ãã«è©²åœããæéã®äž¡æ¹ãæžå°ãå§ãããã以äžå¢å ããŸããã
7æ¥éã®ã°ã©ããèŠããšã_app_startã¡ããªãã¯ã¯å®å šã«é©åã«èŠãã1ç§æªæºã§ãã
ãŸãã_app_startã®äžå€®å€ã5ç§ãè¶ ãããšãããã©ã«ãã§Firebaseãéç¥ãéä¿¡ããããšã远å ããå¿ èŠããããŸãããã ããã芧ã®ãšãããããã«äŸåããã®ã§ã¯ãªããæç€ºçã«ç¢ºèªããŠãã ããã
ã¬ã«ã ããŒã¿ããŒã¹ã®ç¹åŸŽã¯ããããéãªã¬ãŒã·ã§ãã«ããŒã¿ããŒã¹ã§ãããšããããšã§ãããã®åçŽãªäœ¿çšæ³ãORMãœãªã¥ãŒã·ã§ã³ã§ã®äœæ¥ãšãªããžã§ã¯ãã®ãªã³ã¯ã®é¡äŒŒæ§ã«ãããããããã«ã¹ã±ãŒãåé€ã¯ãããŸããã
ãããèæ ®ãããŠããªãå Žåããã¹ãããããªããžã§ã¯ãã¯èç©ãããããªãŒã¯ãããŸããããŒã¿ããŒã¹ã¯çµ¶ãã倧ãããªãããããã¢ããªã±ãŒã·ã§ã³ã®é床äœäžãèµ·åã«åœ±é¿ãåãŒããŸãã
ç§ã¯ããã«ç®±ã®ãªãå€ã§ã¯ãããŸããããé·ãæã£ãŠããã¬ã«ã ã«ã«ã¹ã±ãŒãåé€ã®ãªããžã§ã¯ããã©ã®ããã«è¡ãæã ã®çµéšãå ±æã®è©±ãšè©±ããç§ãã¡ã®å Žåãããã«ããã¢ããªã±ãŒã·ã§ã³ã®èµ·åæéãå€§å¹ ã«ççž®ãããŸããã
ãã®æ©èœã®å·®ãè¿«ã£ãå€èгã«ã€ããŠã®è°è«ã«ãããããããã¬ã«ã ã«ã«ã¹ã±ãŒãåé€ããªãããšã¯èšèšã«ãã£ãŠè¡ãããŸããæ°ããã¢ããªã±ãŒã·ã§ã³ãèšèšããå Žåã¯ããããèæ ®ããŠãã ããããŸãããã§ã«ã¬ã«ã ã䜿çšããŠããå Žåã¯ããã®ãããªåé¡ããªããã©ããã確èªããŠãã ããã