使用协程异步执行房间数据库查询

huangapple go评论59阅读模式
英文:

execute room db queries async using coroutine

问题

以下是您要翻译的内容:

"what is the problem with the codes
db queries freeze ui.
every thing works , but freezing ui when running db query
what is the point that i dont know .
all queries make ui freeze,
when executing Delete query , recycleview animation freezing ,but after commenting the line that execute query , recycleview work smoothly

hilt Module:

@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {

@Provides
fun provideCardDao(passwordDatabase: PasswordDatabase): CardDao {
return passwordDatabase.cardDao()
}

@Singleton
@Provides
fun providesCoroutineScope(): CoroutineScope {

return CoroutineScope(SupervisorJob() + Dispatchers.Default)

}

@Provides
@Singleton
fun providePasswordDatabase(
@ApplicationContext appContext: Context,
coroutineScope: CoroutineScope
): PasswordDatabase {
return Room.databaseBuilder(
appContext,
PasswordDatabase::class.java,
"mydb.db"
)
.addMigrations()
.addCallback(MYDatabaseCallback(coroutineScope))
.setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
.fallbackToDestructiveMigration()
.build()
}
}

card Dao

@Dao
interface CardDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCardDetails(cardDetails : BanksCardModel)

@Query("DELETE FROM CardDetailsTable WHERE id = :id")
suspend fun deleteCardDetails(id : Int)

@Query("SELECT * FROM CardDetailsTable WHERE id = :id")
fun getOneCardDetails(id : Int):LiveData

@Query("SELECT * FROM CardDetailsTable")
fun getAllCardDetails() : LiveData<List>

@Query("SELECT * FROM CardDetailsTable WHERE username LIKE '%${str}%' OR bank_name LIKE '%${str}%' "
)
fun queryOnCards(str:String): LiveData<List>
}

password db

@Database(entities = [ BanksCardModel::class],version = 15,exportSchema = false)
abstract class PasswordDatabase : RoomDatabase() {
abstract fun cardDao() : CardDao
}

repository

@Singleton
class Repository @Inject constructor(private val cardDao: CardDao) {

suspend fun insertCardDetails(cardDetailsItem: BanksCardModel){
cardDao.insertCardDetails(cardDetailsItem)
}
suspend fun deleteCardDetails(id : Int){
cardDao.deleteCardDetails(id)
}
fun getOneCardDetails(id : Int):LiveData{
return cardDao.getOneCardDetails(id)
}
fun getAllCardDetails() : LiveData<List>{
return cardDao.getAllCardDetails()
}
fun queryOnCards(str : String) : LiveData<List>{
return cardDao.queryOnCards(str)
}
}

viewModel

@HiltViewModel
class DetailsViewModel @Inject constructor(
private val repository: Repository
) : ViewModel() {

private var cardDetailsList : LiveData<List>;

init {
cardDetailsList = repository.getAllCardDetails()
}

fun insertCardDetails(cardDetailsItem: BanksCardModel)= viewModelScope.launch {
repository.insertCardDetails(cardDetailsItem)
}
fun deleteCardDetails(id : Int)= viewModelScope.launch {
repository.deleteCardDetails(id)
}
fun getOneCardDetails(id : Int):LiveData{
return repository.getOneCardDetails(id)
}
fun getAllCardDetails() : LiveData<List>{
return cardDetailsList
}

fun queryOnCards(str:String) : LiveData<List>{
return repository.queryOnCards(str)
}

}

//edited

query in searchview

   override fun onQueryTextChange(newText: String?): Boolean {
        
        lifecycleScope.launch {
                viewModel.queryOnCards(newText?:"").collect{
                    val searchedList = it.toMutableList()
                    showingEmptyListAnnounce(searchedList)
                    adapter.updateList(searchedList)
                }
        }

        return true
    }

the update list function in onQueryTextChange -- its using DiffUtils

   fun updateList( updatedList : MutableList<BanksCardModel>){

       val callback = CustomCallback(mList, updatedList)
       val result  = DiffUtil.calculateDiff(callback)
       mList.clear()
       mList.addAll(updatedList)
     result.dispatchUpdatesTo(this)

}
video of screen"

请注意,我已经将其中的HTML转义字符(如&quot;)还原为相应的引号。

英文:

what is the problem with the codes
db queries freeze ui.
every thing works , but freezing ui when running db query
what is the point that i dont know .
all queries make ui freeze,
when executing Delete query , recycleview animation freezing ,but after commenting the line that execute query , recycleview work smoothly

> hilt Module:

@Module
@InstallIn(SingletonComponent::class)
object DatabaseModule {

@Provides
fun provideCardDao(passwordDatabase: PasswordDatabase): CardDao {
    return passwordDatabase.cardDao()
}

@Singleton 
@Provides
fun providesCoroutineScope(): CoroutineScope {
  
    return CoroutineScope(SupervisorJob() + Dispatchers.Default)
}

@Provides
@Singleton
fun providePasswordDatabase(
    @ApplicationContext appContext: Context,
    coroutineScope: CoroutineScope
): PasswordDatabase {
    return Room.databaseBuilder(
        appContext,
        PasswordDatabase::class.java,
        &quot;mydb.db&quot;
    )
        .addMigrations()
        .addCallback(MYDatabaseCallback(coroutineScope))
        .setJournalMode(RoomDatabase.JournalMode.TRUNCATE)
        .fallbackToDestructiveMigration()
        .build()
}
}

> card Dao

@Dao
interface CardDao {

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertCardDetails(cardDetails : BanksCardModel)


@Query(&quot;DELETE FROM CardDetailsTable WHERE id = :id&quot;)
suspend fun deleteCardDetails(id : Int)

@Query(&quot;SELECT * FROM CardDetailsTable WHERE id = :id&quot;)
 fun getOneCardDetails(id : Int):LiveData&lt;BanksCardModel&gt;

@Query(&quot;SELECT * FROM CardDetailsTable&quot;)
fun getAllCardDetails() : LiveData&lt;List&lt;BanksCardModel&gt;&gt;

@Query(&quot;SELECT * FROM CardDetailsTable WHERE username LIKE &#39;%&#39; || :str || &#39;%&#39; OR bank_name LIKE &#39;%&#39; || :str || &#39;%&#39; &quot;
)
 fun queryOnCards(str:String): LiveData&lt;List&lt;BanksCardModel&gt;&gt;
}

> password db

@Database(entities = [ BanksCardModel::class],version = 15,exportSchema = false)
abstract class PasswordDatabase : RoomDatabase() {
abstract fun cardDao() : CardDao
}

> repository

@Singleton
class Repository @Inject constructor(private val cardDao: CardDao) {

suspend fun insertCardDetails(cardDetailsItem: BanksCardModel){
    cardDao.insertCardDetails(cardDetailsItem)
}
suspend fun deleteCardDetails(id : Int){
    cardDao.deleteCardDetails(id)
}
 fun getOneCardDetails(id : Int):LiveData&lt;BanksCardModel&gt;{
    return cardDao.getOneCardDetails(id)
}
fun getAllCardDetails() : LiveData&lt;List&lt;BanksCardModel&gt;&gt;{
    return cardDao.getAllCardDetails()
}
 fun queryOnCards(str : String) : LiveData&lt;List&lt;BanksCardModel&gt;&gt;{
    return cardDao.queryOnCards(str)
}
}

> viewModel

@HiltViewModel
class DetailsViewModel @Inject constructor(
private val repository: Repository
) : ViewModel() {

private var cardDetailsList : LiveData&lt;List&lt;BanksCardModel&gt;&gt;


init {
    cardDetailsList = repository.getAllCardDetails() 
}


fun insertCardDetails(cardDetailsItem: BanksCardModel)= viewModelScope.launch {
    repository.insertCardDetails(cardDetailsItem)
}
 fun deleteCardDetails(id : Int)= viewModelScope.launch {
    repository.deleteCardDetails(id)
}
fun getOneCardDetails(id : Int):LiveData&lt;BanksCardModel&gt;{
   return repository.getOneCardDetails(id)
}
fun getAllCardDetails() : LiveData&lt;List&lt;BanksCardModel&gt;&gt;{
    return cardDetailsList
}

  fun queryOnCards(str:String) : LiveData&lt;List&lt;BanksCardModel&gt;&gt;{
         return repository.queryOnCards(str)
}

}

////edited

> query in searchview

       override fun onQueryTextChange(newText: String?): Boolean {
            
            lifecycleScope.launch {
                    viewModel.queryOnCards(newText?:&quot;&quot;).collect{
                        val searchedList = it.toMutableList()
                        showingEmptyListAnnounce(searchedList)
                        adapter.updateList(searchedList)
                    }
            }

            return true
        }

> the update list function in onQueryTextChange -- its using DiffUtils

       fun updateList( updatedList : MutableList&lt;BanksCardModel&gt;){

           val callback = CustomCallback(mList, updatedList)
           val result  = DiffUtil.calculateDiff(callback)
           mList.clear()
           mList.addAll(updatedList)
         result.dispatchUpdatesTo(this)
 }

video of screen

答案1

得分: 1

LiveData is outdated. Please consider to use Kotlin Flow.

Here is your use case:

lifecycleScope.launch {
   dao.getData().collect { data ->
    //handle data here
   }
}
@Dao
interface MyDao {
     @Query("SELECT * FROM somedata_table")
     fun getData(): Flow<List<SomeData>>
}

Reference

There is a good Google codelab to practice Kotlin coroutine and Room queries

Also please consider to use StrictMode - it will show you this and similar issues in the future.

英文:

LiveData is outdated. Please consider to use Kotlin Flow.

Here is your use case:

lifecycleScope.launch {
   dao.getData().collect { data -&gt;
    //handle data here
   }
}
@Dao
interface MyDao {
     @Query(&quot;SELECT * FROM somedata_table&quot;)
     fun getData(): Flow&lt;List&lt;SomeData&gt;&gt;
}

Reference

There is a good Google codelab to practice Kotlin coroutine and Room queries

Also please consider to use StrictMode - it will show you this and similar issues in future.

huangapple
  • 本文由 发表于 2023年2月16日 08:14:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/75466658.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定