标签: kotlin-flow

使用 Flow 进行实时数据转换

我是否阅读了有关 Flow 的更多信息,我开始认为您可以用与 Flow 类似的内容替换 MutableLiveData switchMap 模式。

您可以通过实现类似的方法来用流替换 LiveData 观察,但我无法想象如何替换 switchMap 部分。

我所说的 switchMap 模式是这样的:

val mutableLiveData: MutableLiveData<SomeClass> = MutableLiveData()
val liveData: LiveData<SomeOtherClass> = mutableLiveData
    .switchMap {
       //call to repo
    }
Run Code Online (Sandbox Code Playgroud)

有没有类似的东西或者我完全错过了一些东西?或者甚至以完全错误的方式思考流程。

design-patterns kotlin android-livedata kotlin-flow

4
推荐指数
1
解决办法
4013
查看次数

与 Livedata 不同,使用 Flow in Room 查询在更新表条目时不会触发刷新,但在删除或插入条目时会起作用

当使用 Livedata 作为 Room 中表上的 select* 查询的返回类型时,然后我观察它,如果我更新/插入/删除该表中的条目,我会得到触发器。然而,当我尝试使用 Kotlin Flow 时,我只得到 2 个触发器。

第一个触发器给出一个空值,因为状态流的初始值为空。第二个触发器是 Room 表中的条目列表。

如果我对数据库执行插入/删除操作,我会收到来自 StateFlow 的触发器。但是,如果我更新条目,Stateflow 不会触发。

注意:更新操作在数据库上正常工作。我使用 DB 检查器进行了检查。

数据类和 DAO

@Entity
data class CartItem (
    @PrimaryKey
    val itemId: Int,
    var itemQuantity: Int=1
)

@Dao
interface CartDao {

    @Query("SELECT * FROM CartItem")
    fun getAllItems(): Flow<List<CartItem>>

    @Update
    suspend fun changeQuantityInCart(cartItem:CartItem)

    @Insert
    suspend fun insert(item: CartItem)

    @Delete
    suspend fun delete(cartItem:CartItem)
}
Run Code Online (Sandbox Code Playgroud)

视图模型

val cartItems: StateFlow<List<CartItem>?> =
        repo.fetchCartItems().stateIn(viewModelScope, SharingStarted.Lazily, null)
Run Code Online (Sandbox Code Playgroud)

分段

viewLifecycleOwner.lifecycleScope.launchWhenStarted {
            viewModel.cartItems.collect {
              Log.e("Update","Update")
 }
Run Code Online (Sandbox Code Playgroud)

android android-room kotlin-flow kotlin-stateflow

4
推荐指数
1
解决办法
3727
查看次数

从 ViewModel 中的 SqlDelight 收集流时出现 java.lang.IllegalStateException

我正在尝试在我的应用程序中使用 SqlDelight 数据库。

在我的 DAO 中,我有一个名为 getRecipeById 的函数来查询数据库并返回域模型流(Recipe)。下面是该函数的实现:(注:RecipeTable 是表的名称,或者我想我应该将其称为 RecipeEntity)

fun getRecipeById(id: Int): Flow<Recipe> {
    return recipeQueries.getRecipeById(id)
        .asFlow()
        .mapToOne()
        .map { recipeTable: RecipeTable ->
            recipeTableToRecipeMapper(recipeTable = recipeTable)
        }
}
Run Code Online (Sandbox Code Playgroud)

然后我的存储库像这样调用这个函数:(注意:recipeLocalDatabase 是我的 DAO)

suspend fun getRecipeById(id: Int): Flow<RecipeDTO> {
    val recipeFromDB: Flow<Recipe> = recipeLocalDatabase.getRecipeById(id)
    return recipeFromDB.map { recipe: Recipe ->
        recipeDTOMapper.mapDomainModelToDTO(recipe)
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我的用例层从存储库调用该函数并传递流程:

suspend fun execute(
    id: Int
): UseCaseResult<Flow<RecipeDTO>>
{
    return try{
        UseCaseResult.Success(recipeRepository.getRecipeById(id))
    } catch(exception: Exception){
        UseCaseResult.Error(exception)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在 ViewModel 中,我正在收集 RecipeDTO 的流程,如下所示:

var recipeForDetailView: MutableState<RecipeDTO> = mutableStateOf( …
Run Code Online (Sandbox Code Playgroud)

android sqldelight kotlin-coroutines kotlin-flow

4
推荐指数
1
解决办法
2762
查看次数

Kotlin Flow - 带结果密封类的 Retrofit 通用函数

我最近正在改造Flow我的存储库。

结果密封类

enum class ApiStatus{
    SUCCESS,
    ERROR,
    LOADING
}

sealed class ApiResult <out T> (val status: ApiStatus, val data: T?, val message:String?) {

    data class Success<out R>(val _data: R?): ApiResult<R>(
        status = ApiStatus.SUCCESS,
        data = _data,
        message = null
    )

    data class Error(val exception: String): ApiResult<Nothing>(
        status = ApiStatus.ERROR,
        data = null,
        message = exception
    )

    data class Loading<out R>(val _data: R?, val isLoading: Boolean): ApiResult<R>(
        status = ApiStatus.LOADING,
        data = _data,
        message = null
    )
}
Run Code Online (Sandbox Code Playgroud)

3 …

retrofit kotlin-flow

4
推荐指数
1
解决办法
2829
查看次数

第一件商品到货后立即发货,后续商品进行退抖处理

这个问题与thisthis相同,但是关于Kotlin流程。

需要实现什么:

  • 第一件商品一到就交付
  • 按照去抖动功能的工作方式对以下所有项目进行去抖动

kotlin kotlin-coroutines kotlin-flow

4
推荐指数
1
解决办法
1016
查看次数

将多个流收集为一个

我正在嵌套启动{}的流程中从数据存储区收集数据。

   viewLifecycleOwner.lifecycleScope.launchWhenStarted { 
                launch { 
                    DataStore.userName.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
                launch {
                    DataStore.userPhone.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
                launch {
                    DataStore.userAddress.collect {
                       // it emits string value
                        Log.e(TAG, it )
                    }
                }
            }
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来收集碎片中的流量?就像在单个 launch{} 块中收集所有数据一样。

android kotlin kotlin-coroutines kotlin-flow

4
推荐指数
1
解决办法
3364
查看次数

为什么在 kotlin 中流收集调用超过两次?

嘿,我正在 android 中的 kotlin flow 工作。我注意到我的 kotlin 流程collectLatest调用了两次,有时甚至更多。我尝试过这个答案,但它对我不起作用。我在我的函数中打印了日志,collectLatest它打印了日志。我正在添加代码

MainActivity.kt

class MainActivity : AppCompatActivity(), CustomManager {

    private val viewModel by viewModels<ActivityViewModel>()
    private lateinit var binding: ActivityMainBinding
    private var time = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        setupView()
    }

    private fun setupView() {
        viewModel.fetchData()

        lifecycleScope.launchWhenStarted {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                viewModel.conversationMutableStateFlow.collectLatest { data ->
                    Log.e("time", "${time++}")
                   ....
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

ActivityViewModel.kt

class ActivityViewModel(app: Application) : AndroidViewModel(app) {

    var conversationMutableStateFlow = MutableStateFlow<List<ConversationDate>>(emptyList()) …
Run Code Online (Sandbox Code Playgroud)

android kotlin kotlin-coroutines kotlin-flow kotlin-stateflow

4
推荐指数
1
解决办法
1万
查看次数

如何连接两个 kotlin 流?

如前所述,我想按顺序连接两个流,因此merge行不通。

例子:

val f1 = flowOf(1, 2)
val f2 = flowOf(3, 4)
val f = concatenate(f1, f2) // emits 1, 2, 3, 4

Run Code Online (Sandbox Code Playgroud)

kotlin kotlin-coroutines kotlin-flow

4
推荐指数
1
解决办法
2888
查看次数

初始化一个没有初始值的 kotlin MutableStateFlow

我正在学习 kotlin flow 并慢慢地将我公司应用程序中的代码从 livedata 转换为 kotlin flow。所以我有疑问:

在我的视图模型中,我有这样的 livedata 变量“状态”:

var status: MutableLiveData = MutableLiveData()

我在 MainActivity 中观察到了它。

现在我想用 Flow 做同样的事情。我转换了所有发射/收集部件和其他部件,一切正常,但有一个问题。这是声明我的变量状态的一部分:

var status: MutableStateFlow<Status> = MutableStateFlow() -> 这段代码给出了错误。我需要传递括号中的参数值

所以我必须这样写:

var status: MutableStateFlow<Status> = MutableStateFlow(Status.Failure("adding value even though I don't want to")) 
Run Code Online (Sandbox Code Playgroud)

谁能解释一下,有没有什么方法可以像以前一样在 livedata 中初始化它而不提供初始值?谢谢

android kotlin kotlin-flow

4
推荐指数
1
解决办法
1万
查看次数

使用 Kotlin Flow 实时更新 Firestore

我想实现具有实时更新的系统(类似于 onSnapshotListener)。我听说这可以用Kotlin Flow来完成。

这是我来自存储库的函数。

 suspend fun getList(groupId: String): Flow<List<Product>> = flow {
        val myList = mutableListOf<Product>()
        db.collection("group")
            .document(groupId)
            .collection("Objects")
            .addSnapshotListener { querySnapshot: QuerySnapshot?,
                                   e: FirebaseFirestoreException? ->
                if (e != null) {}
                querySnapshot?.forEach {
                    val singleProduct = it.toObject(Product::class.java)
                    singleProduct.productId = it.id
                    myList.add(singleProduct)
                }
            }
       emit(myList)
    }
Run Code Online (Sandbox Code Playgroud)

还有我的视图模型

class ListViewModel: ViewModel() {

private val repository = FirebaseRepository()
private var _products = MutableLiveData<List<Product>>()
val products: LiveData<List<Product>> get() = _produkty


init {
    viewModelScope.launch(Dispatchers.Main){
        repository.getList("xGRWy21hwQ7yuBGIJtnA")
            .collect { items ->
                _products.value …
Run Code Online (Sandbox Code Playgroud)

android kotlin firebase google-cloud-firestore kotlin-flow

4
推荐指数
2
解决办法
3156
查看次数