በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

ሁሉም ተጠቃሚዎች በሞባይል አፕሊኬሽኖች ውስጥ በፍጥነት ማስጀመር እና ምላሽ ሰጪ UIን እንደ አጋጣሚ ይወስዳሉ። አፕሊኬሽኑ ለመጀመር ረጅም ጊዜ ከወሰደ ተጠቃሚው ማዘን እና መበሳጨት ይጀምራል። አፕሊኬሽኑን መጠቀም ከመጀመሩ በፊት የደንበኞችን ልምድ በቀላሉ ሊያበላሹት ወይም ተጠቃሚውን ሙሉ በሙሉ ሊያጡ ይችላሉ።

የዶዶ ፒዛ መተግበሪያ በአማካይ ለመጀመር 3 ሰከንድ እንደሚፈጅ እና ለአንዳንድ "እድለኞች" ከ15-20 ሰከንድ እንደሚወስድ ደርሰንበታል።

ከመቁረጡ በታች አስደሳች መጨረሻ ያለው ታሪክ ነው-ስለ ሪልየም የውሂብ ጎታ እድገት ፣ የማስታወሻ ፍሰት ፣ የጎጆ ዕቃዎችን እንዴት እንዳከማች እና ከዚያ እራሳችንን ሰብስበን ሁሉንም ነገር አስተካክለናል።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ
የጽሑፍ ደራሲ፡- ማክስም ካቺንኪን - አንድሮይድ ገንቢ በዶዶ ፒዛ።

የማመልከቻ አዶውን ጠቅ ካደረጉት በኋላ የመጀመሪያው እንቅስቃሴ () ላይ ከቆመበት ጊዜ ጀምሮ እስከ መጨረሻው መጨረሻ ድረስ ያለው ሶስት ሰከንዶች ነው። እና ለአንዳንድ ተጠቃሚዎች የጅምር ጊዜ ከ15-20 ሰከንድ ደርሷል። ይህ እንዴት ሊሆን ይችላል?

ለማንበብ ጊዜ ለሌላቸው በጣም አጭር ማጠቃለያ
የእኛ የሪልየም ዳታቤዝ ያለማቋረጥ አድጓል። አንዳንድ የጎጆ ዕቃዎች አልተሰረዙም፣ ነገር ግን ያለማቋረጥ ይከማቹ ነበር። የመተግበሪያው ጅምር ጊዜ ቀስ በቀስ ጨምሯል። ከዚያ አስተካክለነዋል, እና የጅማሬው ጊዜ ወደ ዒላማው መጣ - ከ 1 ሰከንድ ያነሰ እና ከዚያ በኋላ አልጨመረም. ጽሑፉ ስለ ሁኔታው ​​ትንተና እና ሁለት መፍትሄዎችን ይዟል - ፈጣን እና የተለመደ.

የችግሩን ፍለጋ እና ትንተና

ዛሬ ማንኛውም የሞባይል መተግበሪያ በፍጥነት መጀመር እና ምላሽ ሰጪ መሆን አለበት። ግን ስለ ሞባይል መተግበሪያ ብቻ አይደለም. ከአንድ አገልግሎት እና ኩባንያ ጋር የመገናኘት የተጠቃሚ ልምድ ውስብስብ ነገር ነው። ለምሳሌ, በእኛ ሁኔታ, የመላኪያ ፍጥነት ለፒዛ አገልግሎት ቁልፍ አመልካቾች አንዱ ነው. ማቅረቡ ፈጣን ከሆነ ፒሳው ትኩስ ይሆናል, እና አሁን መመገብ የሚፈልግ ደንበኛ ብዙ መጠበቅ አይኖርበትም. ለመተግበሪያው, በተራው, የፈጣን አገልግሎት ስሜት መፍጠር አስፈላጊ ነው, ምክንያቱም አፕሊኬሽኑ ለመጀመር 20 ሰከንድ ብቻ የሚወስድ ከሆነ ፒሳን ምን ያህል መጠበቅ አለብዎት?

መጀመሪያ ላይ እኛ እራሳችን አንዳንድ ጊዜ አፕሊኬሽኑ ለመጀመር ሁለት ሴኮንዶች ይወስዳል እና ከዚያ ለምን ያህል ጊዜ እንደወሰደ ከሌሎች ባልደረቦች ቅሬታዎችን መስማት ጀመርን ። ግን ይህንን ሁኔታ በተከታታይ መድገም አልቻልንም።

እስከመቼ ነው? አጭጮርዲንግ ቶ ጉግል ሰነድ, የመተግበሪያው ቀዝቃዛ ጅምር ከ 5 ሰከንድ ያነሰ ጊዜ የሚወስድ ከሆነ ይህ እንደ "መደበኛ" ይቆጠራል. ዶዶ ፒዛ አንድሮይድ መተግበሪያ ተጀመረ (በFirebase መለኪያዎች መሠረት _መተግበሪያ_ጀምር) በ ቀዝቃዛ ጅምር በአማካይ በ 3 ሰከንድ ውስጥ - "ትልቅ አይደለም, አስፈሪ አይደለም," እነሱ እንደሚሉት.

ግን ማመልከቻው ለመጀመር በጣም በጣም በጣም ረጅም ጊዜ እንደወሰደ ቅሬታዎች መታየት ጀመሩ! ለመጀመር, "በጣም, በጣም ረጅም" ምን እንደሆነ ለመለካት ወሰንን. እና ለዚህ የFirebase trace ተጠቀምን። የመተግበሪያ ጅምር መከታተያ.

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

ይህ መደበኛ ዱካ ተጠቃሚው አፕሊኬሽኑን በከፈተበት ቅጽበት እና የመጀመሪያው እንቅስቃሴ የተጀመረበት() ላይ ያለውን ጊዜ ይለካል። በFirebase Console ውስጥ ይህ መለኪያ _app_start ይባላል። እንዲህ ሆነ።

  • ከ95ኛ ፐርሰንታይል በላይ ለሆኑ ተጠቃሚዎች የጅምር ጊዜዎች ወደ 20 ሰከንድ የሚጠጉ ናቸው (አንዳንዶችም የበለጠ ይረዝማሉ)፣ ምንም እንኳን መካከለኛው ቀዝቃዛ የጅምር ጊዜ ከ5 ሰከንድ በታች ቢሆንም።
  • የመነሻ ጊዜው ቋሚ እሴት አይደለም, ነገር ግን በጊዜ ውስጥ ያድጋል. ነገር ግን አንዳንድ ጊዜ ጠብታዎች አሉ. የትንታኔ ልኬቱን ወደ 90 ቀናት ስናሳድግ ይህንን ንድፍ አግኝተናል።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

ሁለት ሀሳቦች ወደ አእምሮ መጡ።

  1. የሆነ ነገር እየፈሰሰ ነው።
  2. ይህ "የሆነ ነገር" ከተለቀቀ በኋላ እንደገና ይጀመራል እና እንደገና ይፈስሳል።

"ምናልባት ከመረጃ ቋቱ ጋር የሆነ ነገር አለ" ብለን አሰብን እና ልክ ነበርን። በመጀመሪያ፣ የመረጃ ቋቱን እንደ መሸጎጫ እንጠቀማለን፤ በስደት ጊዜ እናጸዳዋለን። በሁለተኛ ደረጃ, አፕሊኬሽኑ ሲጀምር የውሂብ ጎታ ይጫናል. ሁሉም ነገር አንድ ላይ ይጣጣማል.

በሪልየም ዳታቤዝ ላይ ምን ችግር አለበት?

የውሂብ ጎታው ይዘቶች በመተግበሪያው ህይወት ውስጥ እንዴት እንደሚለዋወጡ, ከመጀመሪያው ጭነት እና በንቃት ጥቅም ላይ በሚውልበት ጊዜ ተጨማሪ ማረጋገጥ ጀመርን. የሪልየም ዳታቤዝ ይዘቶችን በ በኩል ማየት ትችላለህ እስቴቶ ወይም በበለጠ ዝርዝር እና በግልፅ ፋይሉን በ በኩል በመክፈት ሪል ስቱዲዮ. የመረጃ ቋቱን ይዘቶች በADB በኩል ለማየት የሪልም ዳታቤዝ ፋይሉን ይቅዱ፡-

adb exec-out run-as ${PACKAGE_NAME} cat files/${DB_NAME}

በተለያዩ ጊዜያት የውሂብ ጎታውን ይዘቶች ከተመለከትን, የአንድ የተወሰነ አይነት እቃዎች ቁጥር በየጊዜው እየጨመረ መሆኑን ደርሰንበታል.

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ
ስዕሉ ለሁለት ፋይሎች የሪል ስቱዲዮን ቁራጭ ያሳያል-በግራ በኩል - የመተግበሪያው መሠረት ከተጫነ ከተወሰነ ጊዜ በኋላ ፣ በቀኝ በኩል - በንቃት ከተጠቀሙ በኋላ። የነገሮች ብዛት ሊታይ ይችላል ImageEntity и MoneyType በከፍተኛ ሁኔታ አድጓል (የቅጽበታዊ ገጽ እይታው የእያንዳንዱን አይነት እቃዎች ብዛት ያሳያል).

በመረጃ ቋት እድገት እና በጅምር ጊዜ መካከል ያለው ግንኙነት

ቁጥጥር ያልተደረገበት የውሂብ ጎታ እድገት በጣም መጥፎ ነው። ግን ይህ በመተግበሪያው ጅምር ጊዜ ላይ ምን ተጽዕኖ ያሳድራል? ይህንን በActivityManager በኩል መለካት በጣም ቀላል ነው። ከአንድሮይድ 4.4 ጀምሮ logcat ምዝግብ ማስታወሻውን በሕብረቁምፊው እና በሰዓቱ ያሳያል። ይህ ጊዜ አፕሊኬሽኑ ከተጀመረበት ጊዜ አንስቶ እስከ እንቅስቃሴው መጨረሻ ድረስ ካለው የጊዜ ክፍተት ጋር እኩል ነው። በዚህ ጊዜ ውስጥ የሚከተሉት ክስተቶች ይከሰታሉ.

  • ሂደቱን ይጀምሩ.
  • የነገሮች መጀመር.
  • የእንቅስቃሴዎች መፈጠር እና መጀመር.
  • አቀማመጥ መፍጠር.
  • የመተግበሪያ አቀራረብ።

ይስማማናል. ADBን በ -S እና -W ባንዲራዎች ካስኬዱ፣ በሚነሳበት ጊዜ የተራዘመ ውፅዓት ማግኘት ይችላሉ፡

adb shell am start -S -W ru.dodopizza.app/.MainActivity -c android.intent.category.LAUNCHER -a android.intent.action.MAIN

ከዚያ ከያዙት grep -i WaitTime ጊዜ፣ የዚህን መለኪያ ስብስብ በራስ ሰር መስራት እና ውጤቱን በእይታ መመልከት ይችላሉ። ከታች ያለው ግራፍ የመተግበሪያው ጅምር ጊዜ በመተግበሪያው ቀዝቃዛ ጅምር ላይ ያለውን ጥገኝነት ያሳያል።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

በተመሳሳይ ጊዜ, ከ 4 ሜባ ወደ 15 ሜባ ያደገው በመረጃ ቋቱ መጠን እና እድገት መካከል ያለው ግንኙነት ተመሳሳይ ተፈጥሮ ነበር. በአጠቃላይ ፣ ከጊዜ በኋላ (በቀዝቃዛ ጅምር እድገት) ፣ የመተግበሪያው ማስጀመሪያ ጊዜ እና የውሂብ ጎታው መጠን ጨምሯል። በእጃችን ላይ መላምት አለን። አሁን የቀረው ጥገኝነቱን ማረጋገጥ ብቻ ነበር። ስለዚህ, "ፍሳሾቹን" ለማስወገድ ወስነናል እና ይህ ጅምርን ያፋጥነዋል.

ማለቂያ ለሌለው የውሂብ ጎታ እድገት ምክንያቶች

"ፍሳሾችን" ከማስወገድዎ በፊት በመጀመሪያ ለምን እንደታዩ መረዳት ጠቃሚ ነው. ይህንን ለማድረግ, ሪል ምን እንደሆነ እናስታውስ.

ሪል ግንኙነት ያልሆነ የውሂብ ጎታ ነው። በአንድሮይድ ላይ ምን ያህል የ ORM ግንኙነት ዳታቤዝ እንደተገለፀው በነገሮች መካከል ያለውን ግንኙነት በተመሳሳይ መልኩ እንዲገልጹ ያስችልዎታል። በተመሳሳይ ጊዜ, Realm በትንሹ የለውጥ እና የካርታ ስራዎች እቃዎችን በቀጥታ በማህደረ ትውስታ ውስጥ ያከማቻል. ይህ መረጃን ከዲስክ በፍጥነት እንዲያነቡ ያስችልዎታል, ይህም የሪልየም ጥንካሬ እና ለምን እንደሚወደድ ነው.

(ለዚህ ጽሁፍ አላማ ይህ መግለጫ ይበቃናል፡ ስለ ሪልም በቀዝቃዛው ጊዜ የበለጠ ማንበብ ትችላለህ ሰነድ ወይም በእነርሱ ውስጥ አካዳሚ).

ብዙ ገንቢዎች በተዛማጅ የውሂብ ጎታዎች (ለምሳሌ፣ ORM ዳታቤዝ ከ SQL ጋር) የበለጠ መስራት ለምደዋል። እና እንደ የውሂብ መሰረዝን የመሳሰሉ ነገሮች ብዙውን ጊዜ የተሰጡ ይመስላሉ። በሪል ውስጥ ግን አይደለም.

በነገራችን ላይ የካስኬድ መሰረዝ ባህሪው ለረጅም ጊዜ ተጠይቋል። ይህ ክለሳ и ሌላ, ከእሱ ጋር የተያያዘ, በንቃት ተወያይቷል. በቅርቡ እንደሚደረግ ስሜት ነበር. ግን ከዚያ ሁሉም ነገር ወደ ጠንካራ እና ደካማ አገናኞች መግቢያ ተተርጉሟል ፣ ይህ ደግሞ ይህንን ችግር በራስ-ሰር ይፈታል። በዚህ ተግባር ላይ በጣም ንቁ እና ንቁ ነበር። መጎተት ጥያቄበውስጥ ችግሮች ምክንያት ለጊዜው ቆሟል።

ሳይሰርዝ የውሂብ መፍሰስ

በሌለበት የካስካዲንግ ሰርዝ ላይ ከተመኩ መረጃው እንዴት በትክክል ይፈስሳል? የሪልም ዕቃዎችን ከጎጆዎ ከሆነ መሰረዝ አለባቸው።
አንድ (ከሞላ ጎደል) እውነተኛ ምሳሌ እንመልከት። እቃ አለን። 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). ሁሉም የተዘረዘሩ መስኮች የሪልም ዕቃዎች ናቸው። አዲስ ነገር (copyToRealm() / copyToRealmOrUpdate()) ከተመሳሳዩ መታወቂያ ጋር ካስገባን ይህ ነገር ሙሉ በሙሉ ይገለበጣል። ነገር ግን ሁሉም የውስጥ እቃዎች (ምስል፣ ማበጀትEntity እና cartComboProducts) ከወላጅ ጋር ያለውን ግንኙነት ያጣሉ እና በመረጃ ቋቱ ውስጥ ይቆያሉ።

ከነሱ ጋር ያለው ግንኙነት ስለጠፋ ከአሁን በኋላ አናነብባቸውም ወይም አንሰርዛቸውም (በግልጽ ካልደረስናቸው ወይም ሙሉውን "ጠረጴዛ" ካላጸዳን በስተቀር)። ይህንን "የማስታወስ ፍንጣቂዎች" ብለነዋል.

ከሪልም ጋር ስንሰራ ከእንደዚህ አይነት ስራዎች በፊት ሁሉንም አካላት በግልፅ ማለፍ እና ሁሉንም ነገር በግልፅ መሰረዝ አለብን። ይህን ማድረግ ይቻላል, ለምሳሌ, እንደዚህ:

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()
}
// и потом уже сохраняем

ይህን ካደረጉ, ሁሉም ነገር እንደ ሁኔታው ​​ይሰራል. በዚህ ምሳሌ፣ በምስል፣ ማበጀትEntity እና cartComboProducts ውስጥ ሌላ ምንም የጎጆ የሪልም ነገሮች እንደሌሉ እንገምታለን፣ ስለዚህ ምንም ሌሎች የጎጆ ቀለበቶች እና ሰርዝ የሉም።

"ፈጣን" መፍትሄ

ለማድረግ የወሰንነው የመጀመሪያው ነገር በፍጥነት በማደግ ላይ ያሉትን እቃዎች ማጽዳት እና ይህ የመጀመሪያውን ችግራችንን ይፈታ እንደሆነ ለማየት ውጤቱን ያረጋግጡ. በመጀመሪያ, ቀላሉ እና በጣም ሊታወቅ የሚችል መፍትሄ ተደረገ, ማለትም እያንዳንዱ ነገር ልጆቹን የማስወገድ ሃላፊነት አለበት. ይህንን ለማድረግ፣ የጎጆውን የሪልም እቃዎች ዝርዝር የሚመልስ በይነገጽ አስተዋውቀናል፡-

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 ሁሉንም ልጆች እንደ ጠፍጣፋ ዝርዝር እንመለሳለን. እና እያንዳንዱ ልጅ ነገር የNstedEntityAware በይነገጽን መተግበር ይችላል፣ ይህም የሚሰርዝ ውስጣዊ የሪልሜሽን እቃዎች እንዳለው ያሳያል፣ ለምሳሌ 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 የNstedEntityAware በይነገጽን በመጠቀም ሁሉንም የጎጆ ዕቃዎችን በተደጋጋሚ ያስወግዳል፡-

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

ይህን ያደረግነው በጣም በፍጥነት በማደግ ላይ ባሉ ነገሮች ነው እና ምን እንደተፈጠረ አረጋገጥን።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

በውጤቱም, በዚህ መፍትሄ የሸፈንናቸው እቃዎች ማደግ አቆሙ. እና የመሠረቱ አጠቃላይ እድገት ቀንሷል ፣ ግን አላቆመም።

"የተለመደው" መፍትሄ

መሰረቱ ቀስ ብሎ ማደግ ቢጀምርም አሁንም አድጓል። ስለዚህ የበለጠ መመልከት ጀመርን። የእኛ ፕሮጀክት በሪል ውስጥ የውሂብ መሸጎጫ በጣም በንቃት ይጠቀማል። ስለዚህ ለእያንዳንዱ ነገር ሁሉንም የጎጆ እቃዎች መፃፍ ጉልበትን የሚጠይቅ ነው, በተጨማሪም የስህተቶች ስጋት ይጨምራል, ምክንያቱም ኮድን በሚቀይሩበት ጊዜ እቃዎችን መግለጽ መርሳት ይችላሉ.

በይነገጾችን እንዳልጠቀምኩ ማረጋገጥ ፈልጌ ነበር, ነገር ግን ሁሉም ነገር በራሱ እንደሚሰራ.

አንድ ነገር በራሱ እንዲሠራ ስንፈልግ, ነጸብራቅን መጠቀም አለብን. ይህንን ለማድረግ በእያንዳንዱ ክፍል ውስጥ ማለፍ እና የሪል ነገር ወይም የነገሮች ዝርዝር መሆኑን ማረጋገጥ እንችላለን-

RealmModel::class.java.isAssignableFrom(field.type)

RealmList::class.java.isAssignableFrom(field.type)

መስኩ RealmModel ወይም RealmList ከሆነ ፣የዚህን መስክ ነገር ወደ ጎጆ ዕቃዎች ዝርዝር ያክሉ። ሁሉም ነገር ልክ ከላይ እንዳደረግነው አንድ አይነት ነው, እዚህ ብቻ በራሱ ይከናወናል. የ Cascade መሰረዝ ዘዴ ራሱ በጣም ቀላል ነው እና ይህን ይመስላል።

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 በማንፀባረቅ ፣ ሁሉንም የጎጆ የሪልም ዕቃዎችን ያገኛል እና ወደ መስመራዊ ዝርዝር ውስጥ ያስገባቸዋል። ከዚያም በተደጋጋሚ ተመሳሳይ ነገር እናደርጋለን. በሚሰርዙበት ጊዜ ነገሩን ትክክለኛነት ማረጋገጥ ያስፈልግዎታል isValidምክንያቱም የተለያዩ የወላጅ ነገሮች አንድ አይነት ጎጆ ሊኖራቸው ስለሚችል። አዳዲስ ነገሮችን በሚፈጥሩበት ጊዜ ይህንን ማስወገድ እና በቀላሉ መታወቂያ በራስ-ሰር መፍጠር የተሻለ ነው።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

የ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)
}

በውጤቱም በደንበኛ ኮድ ውስጥ ለእያንዳንዱ የውሂብ ማሻሻያ ክወና "cascading delete" እንጠቀማለን. ለምሳሌ፣ የማስገባት ክዋኔ ይህን ይመስላል።

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 ኛ ፐርሰንታይል ተጠቃሚዎች ላይ የሚደርሰው፣ እየቀነሰ መምጣት ጀመረ።

በሪል ረጅም ማስጀመሪያ ውስጥ መሰረዝ እንዴት እንዳሸነፈ የሚገልጽ ታሪክ

የሰባት ቀን ገበታውን ከተመለከቱ፣ የ_app_start መለኪያ ሙሉ ለሙሉ በቂ ይመስላል እና ከ1 ሰከንድ ያነሰ ነው።

እንዲሁም በነባሪነት የ_app_start አማካኝ ዋጋ ከ5 ሰከንድ በላይ ከሆነ ፋየርቤዝ ማሳወቂያዎችን እንደሚልክ ማከል ጠቃሚ ነው። ነገር ግን፣ እንደምናየው፣ በዚህ ላይ መተማመን የለብህም፣ ይልቁንስ ገብተህ በግልጽ አረጋግጥ።

የሪልየም ዳታቤዝ ልዩ ነገር ግንኙነታዊ ያልሆነ የውሂብ ጎታ መሆኑ ነው። ምንም እንኳን የአጠቃቀም ቀላልነት፣ ከኦአርኤም መፍትሄዎች ጋር ተመሳሳይነት እና የነገሮችን ማገናኘት ቢመስልም የካስኬድ ስረዛ የለውም።

ይህ ከግምት ውስጥ የማይገባ ከሆነ ፣ የጎጆ ዕቃዎች ይከማቻሉ እና “ይፈሳሉ”። የመረጃ ቋቱ ያለማቋረጥ ያድጋል፣ ይህ ደግሞ የመተግበሪያውን መቀዛቀዝ ወይም ጅምር ላይ ተጽዕኖ ያሳድራል።

እስካሁን ከሳጥኑ ያልወጣ ነገር ግን ለረጅም ጊዜ ሲነገር የቆየውን በሪልየም ውስጥ ያሉ ነገሮችን በፍጥነት እንዴት ማጥፋት እንደሚቻል ልምዳችንን አካፍያለሁ ይላል и ይላል. በእኛ ሁኔታ ይህ የመተግበሪያውን ጅምር ጊዜ በጣም አፋጥኗል።

ምንም እንኳን የዚህ ባህሪ ቅርብ ገጽታ ላይ ውይይት ቢደረግም, በሪልየም ውስጥ የካስኬድ ስረዛ አለመኖር በንድፍ ይከናወናል. አዲስ መተግበሪያ እየነደፉ ከሆነ፣ ይህን ግምት ውስጥ ያስገቡ። እና ቀድሞውኑ ሪልምን እየተጠቀሙ ከሆነ, እንደዚህ አይነት ችግሮች ካጋጠሙዎት ያረጋግጡ.

ምንጭ: hab.com

አስተያየት ያክሉ