协程中的StateFlow与ShareFlow

转载自:协程中的StateFlow与ShareFlow

流的冷热之分

使用过RxJava的同学都知道,在RxJava中流存在冷流和热流这么一种说法的,那么冷流和热流有什么区别呢?

冷流:在流未进行收集或者订阅的时候,整条操作链是不会运行,并且不会向接收者推送数据。订阅者之间也不会存在值共享
热流:在订阅或者收集之前值就会产生,并且当有新的订阅者时,他会接收到订阅之后流中所发送的所有值,存在值共享
在Flow中也会存在冷流、热流之分,今天介绍的StateFlow与ShareFlow就是属于热流,那么就进入今天的正文

StateFlow

StateFloW是一个可观察的状态容器,我们可以通过value属性进行状态的更新和状态的当前状态值的读取,这一点是不是和我们平常使用flow的时候不一样呢,在冷流中我们是使用emit(),和构建流的同时来进行值的发射

StateFlow的创建

1、使用构造方法进行创建,并且设定一个初始值

val state = MutableStateFlow<String>("default")

2、状态的更新

state.value = "pushNewValue"

3、状态收集(collect是suspend函数,所以收集状态需要在协程作用域范围内)

GlobalScope.launch(Dispatchers.IO){
    state.collect{
        Log.d("StateFlow",it)
    }
}

StateFlow使用示例

下面通过一个示例来演示以下:

class loginviewModel(){
    val loginSuccess = MutableStateFlow<Boolean>(false)
    
    fun login(){
        lifecycleScope.launch{
          repository.login()
            .loading()
            .catch()
            .collect{
               loginSuccess.value = true 
            }
        }
    }
}

HomeActvity.class

class LoginActivity : AppCompatActivity(){
    override fun onCreate(){
        ...
        lifecycleScope.launch{
            viewModel.loginSuccess.collect{
                //UI逻辑
                ....
            }
        }
    }
}

据容器,所以坊间传闻StateFlow会替代LiveData,我们了解下二者有何区别,你就会得到答案

StateFlow在构建时需要给定初始状态值,LiveData是不需要初始状态的
如果当Activity进入后台时,Livedata会自动帮我们把使用方取消注册,但是StateFlow并没有关联生命周期,所以不会停止状态的更新推送,如果需要实现一样的功能,官方推荐我们在lifeCycle.repeatOnLifeCycle中进行数据的收集 ,也可以在生命周期函数中将Job.cancel()

SharedFlow

ShareFlow和StateFlow类似,都是热流,但是SharedFlow更为灵活,但是区别在于SharedFLOW并不支持将旧值发送给新的订阅者,并且可以缓存策略,接下来我们看下怎么使用:
SharedFlow的创建

val connectState = MutableSharedFlow<Boolean>(0,0,BufferOverflow.SUSPEND)

public fun <T> MutableSharedFlow(
    replay: Int = 0,
    extraBufferCapacity: Int = 0,
    onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
): MutableSharedFlow<T> {
    ...
}

上面为MutableSharedFlow的创建源码,需要了解他的三个配置参数

replay :当新的订阅者订阅需要重新将多少旧值重放给它

extraBufferCapacity :除开replay之外的缓冲区大小

onBufferOverflow :缓冲区溢出策略

 SUSPEND:缓冲区满时就会被挂起
 DROP_OLDEST: 缓冲区满时就会删除最旧的值
 DROP_LATEST:删除即将进入缓冲区的最新值

使用emit或者tryEmit进行值的发送

 connectState.tryEmit(false)
 connectState.emit(false)

tryEmit会将发射的结果回调,并且如果缓冲区策略配置为suspend时会将这次数据的发射挂起,知道缓冲区有空间时再进行发射。

emit 当缓冲区没有空间时,该操作就会挂起

SharedFlow的收集

GlobalScope.launch(Dispatchers.IO){
    connectstate.collect{
        ...
    }
}
冷流转换成热流

官方分别提供stateIn使Flow转换成StateFlow以及使用shareIn操作符转换为SharedFlow

class HomeViewModel(){
    val homeState:Flow<ViewState> = flowof{
        ViewState.Loading
    }.stateIn(coroutineScope)
}

使用shareIn进行转换需要了解它的参数配置

public fun <T> Flow<T>.shareIn(
    scope: CoroutineScope,
    started: SharingStarted,
    replay: Int = 0
)
scope: sharedFlow的启动作用域
started:启动策略
SharingStarted.WhileSubscribed() 如果存在数据收集者,上游数据提供方保持活跃状态
SharingStarted.Eagerly 立即启动数据提供方
SharingStarted.Lazily存在数据收集者开始提供数据,并且永远保持活跃状态
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容