رفتن به مطلب
  • 0

ذخیره دیتای دریافتی از سرور در دیتابیس (گوشی)


fun_code

سوال

سلام و عرض ادب

با یه مشکل عجیب مواجه شدم.

زمان ورود به اپلیکیشن میام از سرور لیست استان ها و شهرها رو میگیرم. لیست رشته های تحصیلی رو هم میگیرم.

کلی دیتا هست که بصورت جیسون دریافت میشه.

با کدهای زیر در دیتابیس ذخیره میکنم.

اما مشکل اینجاست که با اولین ورود همه دیتاها ثبت نمیشن و انگار مثلا گاهی 70 درصد دیتاها یا گاهی بیشتر یا کمتر ذخیره میشه.

وقتی چندین مرتبه وارد اپ میشیم به مرور انگار دیتا رو ذخیره و تکمیل میکنه !

مشکل این نقص در ذخیره سازی چیه ؟

 

در کدهای اولین اکتیویتی و در رویداد onCreate این دو تابع فراخوانی میشن و بعد وارد اکتیوتی اصلی میشیم.

   fun countriesStatesCities() = liveData(Dispatchers.IO) {
        emit(Resource.loading(null))
        try {
            emit(Resource.success(mainRepository.countriesStatesCities()))
        }catch (e:Exception){
            emit(Resource.error(null,e.message))
        }
    }

    fun jobsSubJobs() = liveData(Dispatchers.IO) {
            emit(Resource.loading(null))
        try {
            emit(Resource.success(mainRepository.jobsSubJobs()))
        }catch (e:Exception){
            emit(Resource.error(null,e.message))
        }
    }

کدهای MainRepository

    suspend fun countriesStatesCities() = apiProvider.countriesStatesCities()
    suspend fun jobsSubJobs() = apiProvider.jobsSubJobs()

کدهای ApiProvider

    suspend fun countriesStatesCities() = apiInterface.countriesStatesCities()
    suspend fun jobsSubJobs() = apiInterface.jobsSubJobs()

کدهای ApiInterface

    @POST("countries_states_cities")
    suspend fun countriesStatesCities():ArrayList<CountryList>

    @POST("jobs_sub_jobs")
    suspend fun jobsSubJobs():ArrayList<JobList>

کدهای DatabaseRepository

    suspend fun addCountry(country: Country){
        countryDao.insert(country)
    }

    suspend fun addState(state: State){
        stateDao.insert(state)
    }
    suspend fun addCity(city: City){
        cityDao.insert(city)
    }
    suspend fun addJob(job: Job){
        jobDao.insert(job)
    }
    suspend fun addSubJob(subSection: SubSection){
        subJobDao.insert(subSection)
    }

و برای تک تک فیلدها یک فایل کوئری نوشته شده مثلا برای کشور فایل CountyDao

   @Insert(onConflict = OnConflictStrategy.IGNORE)
    fun insert(country: Country)

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

6 پاسخ به این سوال تاکنون داده شده است

ارسال‌های توصیه شده

ببخشید

کدهای اول اشتباه ارسال شدن

در اولین اکتیویتی دو تابع هست که در رویداد onCreate فراخوانی میشن و کدهاشون اینه ، در پست قبلی کدهای مدل بود

    private fun countriesStatesCities(){
        splashViewModel.countriesStatesCities().observe(this) {
            it.let { resource ->
                when (resource.status) {
                    Status.LOADING -> {

                    }
                    Status.SUCCESS -> {
                        val country = resource.data?.get(0)?.countries
                        val state = resource.data?.get(0)?.states
                        val city = resource.data?.get(0)?.cities
                        country?.forEachIndexed { index, country -> splashViewModel.addCountry(country) }
                        state?.forEachIndexed { index, state -> splashViewModel.addState(state) }
                        city?.forEachIndexed { index, city -> splashViewModel.addCity(city) }
                    }
                    Status.ERROR -> {
                    }
                }
            }
        }
    }

    private fun jobsSubJobs(){
        splashViewModel.jobsSubJobs().observe(this) {
            it.let { resource ->
                when (resource.status) {
                    Status.LOADING -> {

                    }
                    Status.SUCCESS -> {
                        val job = resource.data?.get(0)?.jobs
                        val subJob = resource.data?.get(0)?.subJobs
                        job?.forEachIndexed { index, job -> splashViewModel.addJob(job) }
                        subJob?.forEachIndexed { index, subSection -> splashViewModel.addSubJob(subSection) }
                    }
                    Status.ERROR -> {
                    }
                }
            }
        }
    }

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

سلام و درود این روش که موقه ورود این همه دیتا میگیرید و پردازش میکنید که استاندارد نیست اصلا.‌سرعت لانچ رو خیلی پایین میاره. و اینکه چرا livedata استفاده کردین؟مگه قرار نیست فقط دیتا بگیرید و ذخیره کنید تو دیتابیس. چرا از lifecyle استفاده نکردین؟ و نکته دیگه اینکه coroutin ها وابستگی شدید به چرخه حیارت کانتکستی دارن که توش استارت شدن. اگه اکتیویتی بسته بشه coroutin هم بسته میشه

لینک ارسال
به اشتراک گذاری در سایت های دیگر

در ۱۴۰۰/۱۰/۱۷ در ۰۰:۲۲، محمدرضا شاهپیری گفته است:

سلام و درود این روش که موقه ورود این همه دیتا میگیرید و پردازش میکنید که استاندارد نیست اصلا.‌سرعت لانچ رو خیلی پایین میاره. و اینکه چرا livedata استفاده کردین؟مگه قرار نیست فقط دیتا بگیرید و ذخیره کنید تو دیتابیس. چرا از lifecyle استفاده نکردین؟ و نکته دیگه اینکه coroutin ها وابستگی شدید به چرخه حیارت کانتکستی دارن که توش استارت شدن. اگه اکتیویتی بسته بشه coroutin هم بسته میشه

سلام استاد.

راستش چون ممکنه دیتا اضافه بشه گفت لایو باشه تا در صورت بیشتر شدن دیتابیس آپدیت باشه.

و اینکه این دیتا به محض ورود به اپ استفاده داره و ناچارا باید همون اول کار میگرفتم.

البته دیتا در حدی نیست که سرعت بالا اومدن اپ را کم کنه.

ولی اصلا چرا باید یهو نصف دیتا ثبت بشه ؟!

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

سلام مجدد

استاد عزیز ، امیدوارم پرسشم خنده دار نباشه

چون زیاد با کاتلین کار نکردم در جریان این موارد نیستم

کاتلین خیلی با b4a متفاوته

در لینک زیر lifecycle رو خوندم.

https://camposha.info/android-examples/android-activity-lifecycle/#gsc.tab=0

تنها تفاوتی که دیدم اینه که تمام رویدادهای create و start و resume و ... رو نوشته

منم نوشتم و فراخوانی توابع رو در start گذاشتم اما مشکل حل نشد.

تنها زمانی حل میشه که با وقفه مثلا 5 ثانیه ای اکتیویتی رو ببندم و وارد اکتیویتی بعدی بشم.

در اون صورت دیتاها بصورت کامل ثبت میشن.

دقیقا بقول شما دیتا ثبت نشده اکتیویتی بسته میشه و وارد اکتیویتی بعدی میشه.

 

لینک ارسال
به اشتراک گذاری در سایت های دیگر

بله عزیز تا زمانی که اطلاعات fetch نشده و تو دیتابیس ذخیره نشده نباید ببندید اکتیویتی رور. از lifecyclescope استفاده کنید یه بلاک با withContext و دیسپچر  IO توش ایجاد کنید. تمامی مراحل دریافت و ذخیره اطلاعات رو اینجا انجام بدید بعد اکتیویتی رو ببندید.مبحث coroutin تو کاتلین مبحث فوقلاده مهمی هست حتما یه تایم یک هفته ای روش بزارید و کامل درکش کنید

لینک ارسال
به اشتراک گذاری در سایت های دیگر

در ۱۴۰۰/۱۰/۱۷ در 09:32، محمدرضا شاهپیری گفته است:

بله عزیز تا زمانی که اطلاعات fetch نشده و تو دیتابیس ذخیره نشده نباید ببندید اکتیویتی رور. از lifecyclescope استفاده کنید یه بلاک با withContext و دیسپچر  IO توش ایجاد کنید. تمامی مراحل دریافت و ذخیره اطلاعات رو اینجا انجام بدید بعد اکتیویتی رو ببندید.مبحث coroutin تو کاتلین مبحث فوقلاده مهمی هست حتما یه تایم یک هفته ای روش بزارید و کامل درکش کنید

سلام استاد عزیز

اول سرچ کنم ببینم این چی هست...

بعد ببینم میتونم استفاده کنم و دو تابعی که دیتا فراخوانی و ذخیره میکنن رو داخلش قرار بدم. دیسپچر  IO  هم همینطور ...

فعلا با قرار دادن وقفه زیاد پس از دریافت دیتا مشکل رو حل کنم تا بعد خط بالایی رو اجرا کنم. چون الان با مشکل بزرگی مواجه هستم و زمان کم.

استاد بینهایت متشکرم بابت راهنماییتون

چشم مبحث coroutin  رو هم حتما مطالعه میکنم.

لینک ارسال
به اشتراک گذاری در سایت های دیگر

بایگانی شده

این موضوع بایگانی و قفل شده و دیگر امکان ارسال پاسخ نیست.

  • کاربران آنلاین در این صفحه   0 کاربر

    • هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.
×
×
  • اضافه کردن...