Wil*_*ill 4 android kotlin rx-java android-room kotlin-coroutines
我已经将一个示例程序从Java/SQLite转换为Kotlin/Room.
我正在努力在后台线程中实现带有返回值的查询.
有人问过,但是我无法让它发挥作用.我已经阅读了类似问题的答案,但有些已被弃用,或者某些解决方案似乎很复杂,应该是微不足道的.
当我需要使用查询的返回值时,我真的很难提出一个简单的解决方案.
(如果我使用allowMainThreadQueries()强制在主线程中进行查询,那么一切正常
这是我想在后台线程中进行查询的函数之一:
fun getCrimes(): List<Crime> {
val crimes = crimesDAO.getAllCrimes() as ArrayList<Crime>
return crimes
}
Run Code Online (Sandbox Code Playgroud)
我可以调用函数如下,它可以工作,但这意味着我需要在其他类中添加异步调用,它看起来不优雅:
AsyncTask.execute {
mCrimes = getCrimes() as ArrayList<Crime>
}
Run Code Online (Sandbox Code Playgroud)
==>我想修改getCrimes本身让它在后台运行查询,如:(不正确的代码如下)
fun getCrimes(): List<Crime> {
var crimes: ArrayList<Crime>
AsyncTask.execute {
crimes = crimesDAO.getAllCrimes() as ArrayList<Crime>
}
return crimes // This is wrong as crimes in not initialized
}
Run Code Online (Sandbox Code Playgroud)
我查看了kotlin coroutines,Live Data和rxjava但是找不到一个简单的方法.
这是数据类:
@Entity(tableName = "crimes_table")
class Crime {
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name="id")
var id: Long = 0
@ColumnInfo(name="uuid")
@TypeConverters(UUIDConverter::class)
var mId: UUID = UUID.randomUUID()
@ColumnInfo(name="title")
var mTitle: String? = null
@ColumnInfo(name="date")
@TypeConverters(DateConverter::class)
var mDate: Date? = Date()
@ColumnInfo(name="solved")
var mSolved: Boolean = false
}
Run Code Online (Sandbox Code Playgroud)
这是DAO:
@Dao
interface CrimesListDAO {
@Query("SELECT * FROM crimes_table")
fun getAllCrimes(): List<Crime>
@Query("SELECT * FROM crimes_table WHERE uuid = :uuidString LIMIT 1")
fun getOneCrime(uuidString: String): Crime
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertCrime(crime: Crime)
@Update(onConflict = OnConflictStrategy.REPLACE)
fun updateCrime(crime: Crime)
@Delete
fun deleteCrime(crime: Crime)
}
Run Code Online (Sandbox Code Playgroud)
这是DatabaseApp类:
@Database(entities = [(Crime::class)], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun crimesListDAO(): CrimesListDAO
}
Run Code Online (Sandbox Code Playgroud)
这是我实例化数据库的方式:
class ApplicationContextProvider : Application() {
...
companion object {
var database: AppDatabase? = null
...
}
override fun onCreate() {
super.onCreate()
ApplicationContextProvider.database = Room.databaseBuilder(this, AppDatabase::class.java, "crimeBase.db").build()
}
}
Run Code Online (Sandbox Code Playgroud)
转动你的阻止功能
fun getCrimes() = crimesDAO.getAllCrimes() as List<Crime>
Run Code Online (Sandbox Code Playgroud)
进入暂停状态:
suspend fun getCrimes() = withContext(Dispatchers.IO) {
crimesDAO.getAllCrimes() as List<Crime>
}
Run Code Online (Sandbox Code Playgroud)
要调用可挂起的函数,必须首先启动一个协程:
override fun onSomeEvent() {
(context as CoroutineScope).launch {
val crimes = getCrimes()
// work with crimes
}
}
Run Code Online (Sandbox Code Playgroud)
要了解如何使您context
成为a CoroutineScope
,请参阅上的文档CoroutineScope
.
默认情况下,使用 Room 对数据库的所有请求都必须在后台线程中进行。为什么不使用协程?你可以将它与这样的东西一起使用:
suspend fun retrieveCrimes(): List<Crime> {
return async {
delay(5000)
1
}.await()
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3350 次 |
最近记录: |