这是我的 FirebaseOTPVerificationOperation 类,其中定义了我的 MutableStateFlow 属性,并更改了值,
@ExperimentalCoroutinesApi
class FirebaseOTPVerificationOperation @Inject constructor(
private val activity: Activity,
val logger: Logger
) {
private val _phoneAuthComplete = MutableStateFlow<PhoneAuthCredential?>(null)
val phoneAuthComplete: StateFlow<PhoneAuthCredential?>
get() = _phoneAuthComplete
private val _phoneVerificationFailed = MutableStateFlow<String>("")
val phoneVerificationFailed: StateFlow<String>
get() = _phoneVerificationFailed
private val _phoneCodeSent = MutableStateFlow<Boolean?>(null)
val phoneCodeSent: StateFlow<Boolean?>
get() = _phoneCodeSent
private val _phoneVerificationSuccess = MutableStateFlow<Boolean?>(null)
val phoneVerificationSuccess: StateFlow<Boolean?>
get() = _phoneVerificationSuccess
fun resendPhoneVerificationCode(phoneNumber: String) {
_phoneVerificationFailed.value = "ERROR_RESEND"
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的视图模式,我在那里监听 stateflow 属性的变化,如下所示,
class OTPVerificationViewModal @AssistedInject constructor(
private …Run Code Online (Sandbox Code Playgroud) kotlin kotlin-coroutines kotlin-coroutines-flow kotlin-coroutine-channel
SharedFlow刚刚在协程 1.4.0-M1 中引入,它旨在替换所有BroadcastChannel实现(如设计问题描述中所述)。
我有一个用例,我使用 aBroadcastChannel来表示传入的 Web 套接字帧,以便多个侦听器可以“订阅”这些帧。当我移动到 a 时,我遇到的问题SharedFlow是当我收到关闭帧或上游错误时我无法“结束”流程(我想这样做是为了通知所有订阅者流程已经结束)。
当我想有效地“关闭” 时,如何使所有订阅终止SharedFlow?有没有办法区分正常关闭和异常关闭?(如频道)
如果MutableSharedFlow不允许将流的结尾传达给订阅者,如果BroadcastChannel被弃用/删除,有什么替代方法?
初始化 Kotlin Coroutine Flow 并在 Flow 创建后修改其值。
所需的功能类似于 MutableLiveData 的功能setValue,它允许将数据添加到现有的 MutableLiveData 对象。在下面的示例中setValue,调用FeedViewModel.kt中的_feedMutableLiveData 值以更新该值。
这按预期工作,发出FeedFragment.kt 中的值
FeedViewState.kt
data class _FeedViewState(
val _feed: MutableLiveData<List<Tweet>> = MutableLiveData()
)
data class FeedViewState(private val _feedViewState: _FeedViewState) {
val feed: LiveData<List<Tweet>> = _feedViewState._feed
}
Run Code Online (Sandbox Code Playgroud)
FeedViewModel.kt
class FeedViewModel(...) : ViewModel() {
private val _feedViewState = _FeedViewState()
val feedViewState = FeedViewState(_feedViewState)
init {
viewModelScope.launch(Dispatchers.IO) {
feedRepository.getFeed().collect { results ->
when (results.status) {
LOADING -> ...
SUCCESS -> …Run Code Online (Sandbox Code Playgroud) 随着zip还是combine这只是可能的,如果我不想念什么只有2流结合起来,我没能看到流动的联合收割机列表或任何公共方法vararg。
例如
apiHelper.getUsers()
.zip(apiHelper.getMoreUsers()) { usersFromApi, moreUsersFromApi ->
val allUsersFromApi = mutableListOf<ApiUser>()
allUsersFromApi.addAll(usersFromApi)
allUsersFromApi.addAll(moreUsersFromApi)
return@zip allUsersFromApi
}
Run Code Online (Sandbox Code Playgroud)
我需要来自 REST api 的前 5 个页面,并并行获取它们并组合结果,进行一些映射,并对组合数据进行过滤。我可以将它们与flow还是应该通过 coroutineScope 并使用 async 来进行并行请求?
我有一个使用三个 LiveData 源的 MediatorLiveData。当它们中的任何一个发出一个新值并且我至少有一个值时,我使用这三个值来生成 UI 的输出。
其中两个来源是关于如何对列表进行排序和过滤的用户设置,第三个是从 Room 数据库 Flow 中提取的列表数据。
它看起来像这样:
val thingsLiveData: LiveData<List<Thing>> = object: MediatorLiveData<List<Thing>>() {
var isSettingA: Boolean = true
var settingB: MySortingEnum = MySortingEnum.Alphabetical
var data: List<Thing>? = null
init {
addSource(myRepo.thingsFlow.asLiveData()) {
data = it
dataToValue()
}
addSource(settingALiveData) {
isSettingA= it
dataToValue()
}
addSource(settingBLiveData) {
settingB= it
dataToValue()
}
}
private fun dataToValue() {
data?.let { data ->
viewModelScope.launch {
val uiList = withContext(Dispatchers.Default) {
produceUiList(data, isSettingA, settingB)
}
value = listItems
}
} …Run Code Online (Sandbox Code Playgroud) android kotlin android-room kotlin-coroutines kotlin-coroutines-flow
我开始学习 Kotlin Flow 和 Coroutines,但我不知道如何使下面的代码起作用。我究竟做错了什么?
interface MessagesListener {
fun onNewMessageReceived(message: String)
}
fun messages(): Flow<String> = flow {
val messagesListener = object : MessagesListener {
override fun onNewMessageReceived(message: String) {
// The line below generates the error 'Suspension functions can be called only within coroutine body'
emit(message)
}
}
val messagesPublisher = MessagesPublisher(messagesListener)
messagesPublisher.connect()
}
Run Code Online (Sandbox Code Playgroud) 我目前正在使用 Kotlin 协程和流程。在我的场景中, aMutableStateFlow代表连接状态 ( CONNECTING, CONNECTED, CLOSING, CLOSED)。也可以登录、注销和再次登录。
为了进一步使用连接,我必须检查状态并等到它是CONNECTED. 如果已经是CONNECTED,我可以继续。如果没有,我必须等到状态达到CONNECTED. 该connect()调用不会返回通过可更新回调马上,结果被传播MutableStateFlow。我目前的想法是做以下事情:
connect()
if (connectionState.value != State.CONNECTED) { // connectionState = MutableStateFlow(State.CLOSED)
suspendCoroutine<Boolean> { continuation ->
scope.launch { // scope = MainScope()
connectionState.collect {
if (it == State.CONNECTED) {
continuation.resume(true)
}
}
}
}
}
// continue
Run Code Online (Sandbox Code Playgroud)
由于我对这个主题还很陌生,我不知道这是否是一种好的做法,而且我也无法在 Kotlin 文档中找到更合适的概念。有没有更好的方法来做到这一点?
有zip功能可以压缩两个Flows。有什么东西可以将三个(或更多)压缩Flows在一起吗?
如果没有,你能帮我实现它的扩展功能吗?就像是:
flow.zip(flow2, flow3) { a, b, c ->
}
Run Code Online (Sandbox Code Playgroud) 我正在试验协程,但不确定是否将 coroutineScope 传递给普通的 Kotlin 用例。这种方法会造成内存泄漏吗?
假设我们正在 VM 中初始化我们的 UseCase 并尝试传递viewModelScope:
class UploadUseCase(private val imagesPreparingForUploadUseCase: ImagesPreparingForUploadUseCase){
fun execute(coroutineScope: CoroutineScope, bitmap: Bitmap) {
coroutineScope.launch {
val resizedBitmap = withContext(Dispatchers.IO) {
imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
是安全码吗?如果我在 VM 中声明这个确切的代码没有区别吗?如果不是,那意味着我可以将 coroutineScope 作为构造函数参数传递......现在我最初认为我应该通过以下方式创建我的 execute 方法:
fun CoroutineScope.execute(bitmap: Bitmap) {
launch {
val resizedBitmap = withContext(Dispatchers.IO) {
imagesPreparingForUploadUseCase.getResizedBitmap(bitmap, MAX_SIZE)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,我们使用扩展函数以便方法使用父协程范围。这意味着,我不需要将 coroutineScope 作为参数传递,只需更改方法即可使用扩展函数。
但是,令我惊讶的是,VM 看不到此方法可用!为什么这个方法不能从VM调用?
这在 VM 中标记为红色:
private fun uploadPhoto(bitmap: Bitmap, isImageUploaded: Boolean) {
prepareDataForUploadingUseCase.execute(bitmap)
}
Run Code Online (Sandbox Code Playgroud)
这在 …
kotlin android-mvvm kotlin-coroutines kotlin-coroutines-flow
我读过类似的主题,但找不到正确的答案:
在我的Repository班级我感冒了Flow,我想分享给 2 Presenters/ViewModels所以我的选择是使用shareIn运算符。
让我们看一下 Android 文档的示例:
val latestNews: Flow<List<ArticleHeadline>> = flow {
...
}.shareIn(
externalScope, // e.g. CoroutineScope(Dispatchers.IO)?
replay = 1,
started = SharingStarted.WhileSubscribed()
)
Run Code Online (Sandbox Code Playgroud)
什么文档建议externalScope参数:
用于共享流的 CoroutineScope。这个范围应该比任何消费者活得更久,以根据需要保持共享流的活动。
但是,寻找有关如何停止订阅 aFlow的答案,第二个链接中投票最多的答案说:
解决方案不是取消流程,而是取消流程的范围。
对我来说,这些答案在SharedFlow的情况下是矛盾的。不幸的是,即使在调用它之后,我的Presenter/ViewModel仍然会收到最新的数据onCleared。
如何防止?这是我如何Flow在我的Presenter/ 中使用它的示例ViewModel …
android kotlin kotlin-coroutines kotlin-flow kotlin-coroutines-flow