Я преобразовал пример программы из Java / SQLite в Kotlin / Room.
Я пытаюсь реализовать запросы с возвращаемыми значениями в фоновом потоке.
Это было задано, но яне мог заставить его работать.Я прочитал ответы на подобные вопросы, но некоторые устарели, или некоторые решения кажутся сложными для чего-то, что должно быть тривиальным.
Я действительно озадачен, придя к простому решению, когда мне нужно использовать возвращаемое значение запроса.
(Все работает как надо, если я заставляю делать запросы в главном потокеwith allowMainThreadQueries ())
Это одна из функций, которую я хотел бы сделать для выполнения запроса в фоновом потоке:
fun getCrimes(): List<Crime> {
val crimes = crimesDAO.getAllCrimes() as ArrayList<Crime>
return crimes
}
Я могу вызвать функцию следующим образом, и она работаетно это означало бы, что мне нужно добавить асинхронные вызовы в другие классы, и это не выглядит элегантно:
AsyncTask.execute {
mCrimes = getCrimes() as ArrayList<Crime>
}
==> Я хотел бы изменить сам 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
}
Я изучил сопрограммы kotlin, 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
}
Это 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)
}
Это класс DatabaseApp:
@Database(entities = [(Crime::class)], version = 1)
abstract class AppDatabase : RoomDatabase() {
abstract fun crimesListDAO(): CrimesListDAO
}
Вот как я создаю экземпляр базы данных:
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()
}
}