我读到在GlobalScope上运行例程是不好的做法。

现在正在做的是:

    class SplashScreen : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash_screen)


        DataBaseHelper.isDbEmpty(this, object : DataBaseHelper.OnCompleteCheckDB {
            override fun isDBEmpty(result: Boolean) {
                //handle result
            }
        })
    }
}

DatabseHelper:
class DataBaseHelper() {

companion object {
    fun isDbEmpty(context: Context, param: OnCompleteCheckDB) {

        val db = AppDatabase(context)
        GlobalScope.launch(Dispatchers.IO) {
            val count = db.movieDao().countElements() <= 0
            withContext(Dispatchers.Main) {
                param.isDBEmpty(count)
            }
        }
    }
}
}

它有效,但是是不好的做法吗?如果希望在ActivityScope上运行它,应该更改什么?

最佳答案

lifecycle-runtime-ktx库中提供了lifecycleScope扩展名,请参见Use Kotlin coroutines with Architecture components。只需将库添加到您应用的build.gradle

...
dependencies {
  ...
  implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
}

如果您正在使用viewModelScope库,也可以使用ViewModel。乍一看,应该将这种逻辑移到 View 模型中,以便在配置更改期间保留查询结果。但是,由于问题与 Activity 范围有关,因此让我们使用lifecycleScope

我还用suspend函数代替了回调。协程可以很好地替代回调,因此最好在可能的情况下使用协程。

还有一件事情,多次创建一个新的AppDatabase实例似乎不是一个好主意。最好一次创建一次,然后在整个应用程序中重复使用。您可以为此使用依赖注入(inject),请参见Manage dependencies between components

class DataBaseHelper() {
    companion object {
        suspend fun isDbEmpty(context: Context, param: OnCompleteCheckDB) = withContext(Dispatchers.IO) {
            val db = AppDatabase(context)
            db.movieDao().countElements() <= 0
        }
    }
}

class SplashScreen : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_splash_screen)

        lifecycleScope.launch {
            const dbIsEmpty = DataBaseHelper.isDbEmpty(this)
            //handle result
        }
    }
}

10-08 03:39