Android how to know when database has finished creating in MVVM

FabZanna :

I have some json data saved in the assets folder. I use this code to read and process it into data classes I have created:

fun getJsonDataFromAssets(context: Context, fileName: String): String =
    context.assets.open(fileName).bufferedReader().use { it.readText() }

inline fun <reified T> extractJsonData(context: Context, jsonName: String): List<T> {
    val jsonList = JSONArray(getJsonDataFromAssets(context, jsonName))
    val gson = Gson()
    val extractedList = mutableListOf<T>()
    for (i in 0 until jsonList.length()) {
        val jsonObject = jsonList.getJSONObject(i).toString()
        val elementOfT = gson.fromJson(jsonObject, T::class.java)
        extractedList.add(elementOfT)
    }
    return extractedList
}

Then I add those data classes to my room db callback with this code:

private class DatabaseCallback(
        private val context: Context,
        private val scope: CoroutineScope
    ) :
        RoomDatabase.Callback() {
        override fun onCreate(db: SupportSQLiteDatabase) {
            super.onCreate(db)
            instance?.let { database ->
                scope.launch {
                    val ownerDao = database.ownerDao()
                    val dogDao = database.dogDao()
                    val catDao = database.catDao()
                    initializeList("owner.json", ownerDao)
                    initializeList("dog.json", dogDao)
                    initializeList("cat.json", catDao)
                }
            }
        }

        suspend inline fun <reified T> initializeList(jsonName:String, dao: IDao<T>) {
            val jsonList = extractJsonData<T>(context, jsonName)
            dao.addAllT(jsonList)
        }
    }

In my main activity I observe Livedata and use it to populate a recyclerview as soon as the app launches. However this make the recyclerview blank for some time.

How can I add a progress bar or whatever else until the database has been created?

CommonsWare :

In general, I would handle this by using Room's support for populating your database from an asset. That's a relatively recent addition to the Room API, and it should be faster than what you have.

Ignoring that, you would need to pass something into your DatabaseCallback constructor (e.g., a function type) that could be called from your onCreate() function when your work is completed. Whatever is creating your database (e.g., a repository) would provide that DatabaseCallback constructor parameter and deal with the result.

So, for example, your constructor could be:

private class DatabaseCallback(
    private val context: Context,
    private val scope: CoroutineScope,
    private val onDone: () -> Unit
)

...and onCreate() could call onDone() after inserting all the entries. Or, onDone could be a Channel on which you offer() the result. Whoever is creating the DatabaseCallback would supply the lambda expression or Channel or whatever, then use that to find out when the work completed.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=174499&siteId=1