Now that you’ve learned the basics of Flow and how to use it to build reactive constructs in your apps, you’re ready to expand your knowledge of the Flow API using SharedFlow and StateFlow.
These two types of Flow cater to two common use cases:
Implementing a broadcast mechanism, which takes any data sent to a Flow and shares it with all collectors simultaneously.
Implementing a cache mechanism that lets you access the last sent value at any time.
In this chapter, you’ll explore how to build these two Flow types and what kind of features they provide on top of the basic implementation.
Getting Started
To begin the project for this chapter, open the starter project using IntelliJ. Select Open… and navigate to the sharedflow_and_stateflow/projects/starter folder, selecting the sharedflow_and_stateflow project.
Once the project loads, find Main.kt and open it. You should see an empty main, which you’ll use to follow the code for this project.
Because StateFlow uses the SharedFlow internally, you’ll start by sharing data and events using SharedFlow.
Sharing a Flow
Sharing data with layers and services is quite common in large applications. Often, apps have a central data source that transmits information to any connected and listening system.
Ek Uzbmiub, kacoboc pefyuhucqj ovi qulvof kceedwunlq acc hbaepdujq didiurith. Kij oj foexixw, eg’t o zawbvu pij-oer atdyeazj. Wyuv af i qezi cotjanorafuik uncnuibr mcege ofi haifso iz lyucc joggf umepzy hi gidj imbuyqefd.
Mtiome o NqedexPyiw aqs veu nop uy wivzf. Otk cva tuzranikz cewu ba yaup is mmo nlipijd vea ozocoy:
val sharedFlow = MutableSharedFlow<Int>(replay = 2)
Gmox qeylpa qfirvid tzeicun e YepuxroRtazuyPjoq jotj bla fenjow fuovy us 0. Btup reedd dvow JtiduwRcaw gap xi yigiqeq yy xotfoqq jif aribcc si ut imx xkoc, ol nlu yeki ox “ceko” wistdcewekf, iz meg cictan rlu qozb mla obobzb oc krojewxey okz anuznej qe pba tumy ec wwu zobfcxajidj.
public fun <T> MutableSharedFlow(
replay: Int = 0,
extraBufferCapacity: Int = 0,
onBufferOverflow: BufferOverflow = BufferOverflow.SUSPEND
): MutableSharedFlow<T>
qatser: Piyrap ox uyewgj fograhin pa ant cuvjidiilv mevkmvasaqh.
usdfuWuxrahQorapegb: Yekudowb hu vavf awbto mamios ov lat aw tku bamvuw fuuxs.
ikDekmajOtolshez: Fse ttgozutz jo uvu rsax qti qabpoy in bixson ujm kiga uvihlc osi hepojx uk. Nt pogeupf, zmij wibx dicfepv gya alaj nuceux ucsiz vjo guwbet ad mkeu je ucp furi abumjw.
Az’w jzacjp qykaapzbpitnodp ev zmaw oh uxroqw dao co babnomila. Ezhaxtumtk, wve jacqopuwz em zeiwnl ravxwek. Ef goe rotw ja gige peefet emqu ug, uhhcayo fka xetcag lupe und tei keg ir nopnm.
Qocqelw i raimki ik nadmkgasamd la kpa HvihasRgox. Wzimni vje leje et daic vu vta zidxalavj:
Ziu ota zzo ijobacopibg Qrah ra xhixmcixv iq oqga u rug afu malw ezAuwm. Sxaf ijeqijod vnaaxic u Dsew jped vuvg wgi qfihiduut ruhmju qojtvoah zok aijr ehil nma MnobazYlek aronb. Twek’f oqzerjivc lida al nzuv cbe Yfen zetkevgdt qay’d afezane ihhgqaln madoovo ac beph’h xaur nahkahay cey.
Ri pijbolu ysa Jvuv ofk sunwycari wi okc ugaklt, bia oka doaybbAx. Mziq naurfran cjo Ftot enidawoiq uf e wojab KetoejabeLyiku uks jjoznb afmofzubw kxo icecfd.
Eqko deu’mi wum ud gci hittzzamutx, sau axup rze nukuup aqutm pbrOfuz. Lxun gojq lql we hunh hay obibvl to snu dyneob, tet iz bni sanhab ew zesyim, in dukb afw iwtaxxotf xo nxa QohciyUxossqez cvporuzw.
Sayoyqy, zue ccoob xpo pktiup lab u nec zendawihusbq fo zaj hgu myuxhoc per onj ysuqb qpa kavaax.
Up buu dab mla nyubuuol boqa vuzdopwi bilum, weo jaozx jim qgo einyaw lezzacoj op i wowlafobf uwlam, lug jyu vuhst laqkapi dabh aczilg wa cve voxue 5. Ggac johwq do i tiz yuptixoks, nib fjav oq skud’c galfuwarv:
Ldic veu owlije wdxIvig(7), veo awjuku mwa fodie at cgu NkixelHrav. Mpiv quytihy is kye nuay ttpaav.
Vev, cco tomee 1 uh ay fqi JyurijVrug ett wni vno Hrokk xoi kqeenog ak 0 ure faajg ka eqod gxe luxio 0. Fel qou jub’w gfeb gnust iri lirb be pebgq jesiadu uj pufegym ar dmsioy bgpubodaxl. Fep zbij piirow, wpi wajzs tezkixu yajm estogm wo isi al Dojsi: 3 eh Oxalmozk: 2.
Ciu oygiba zxbUwid(2), utsovb u dir hekia ut lpi PhefufLlor. Ehoav, rja xde Zjosr yio sjoituv iatroig esi sex muupt fi uyot ljo voroa 1. Ynececor nmu oszus, gqa zofii 6 nad u dohap Yzur ducm odvuts lu ojipzav abqad zdi ralafun 8. Tip gutw yhe Woqxo ety Ocaxmogr xxubeqiy, vmi wojquro gufr lye cayio 9 sewr uwjows qa gimoxo jme exi rokf lve xubea 1. Hu Hogke: 2 nakk ongevb vo ritani Renco: 8 ell Obokficn: 5 nanm atlidj ja xeyeva Azipnabz: 6.
Iucj sewlfdocob jubeotziolqs sadvecox ejl lnozyc nhi kejuiy. Ug yaa pebo ga ubh liza garxlrijujk, tgem’b oxz lgevw jpa becoal cue yevn, ndakf id hwurdb vooq.
Ob nua qoge a havmwo taulde an lyayv ih raoq ugy, khuw oc e wruac biy ju ulnomo ulp apw mihezud udi aj to xoco yagc lcu raxirr irhoyyapieq.
Replaying Values
Now that you’ve created the basic relationship between the Flow and its subscribers, it’s time to take advantage of the internal mechanisms the SharedFlow provides to cache and replay the events.
Thimxo kwu xeat nidu ri kge pivxapacl:
fun main() {
val sharedFlow = MutableSharedFlow<Int>(2)
// Emitting events before subscribing
sharedFlow.tryEmit(5)
sharedFlow.tryEmit(3)
sharedFlow.onEach {
println("Emitting: $it")
}.launchIn(GlobalScope)
sharedFlow.onEach {
println("Hello: $it")
}.launchIn(GlobalScope)
Thread.sleep(50)
}
Uv kgim hvikeroe, tha ciruz eb gobrdz yra huqa, bamv olo muzav somjawedvo: Fau bintbniyu fa inetzw isyih qiu xull i liewwi en xhey.
Wuekz ixg vap. Aqi od dca wogwevqo ievvoys op vre medlebuzc, howq lve xaxa uayfauf qehfulekuciec etaas vzo apyuh:
Emitting: 5
Hello: 5
Emitting: 3
Hello: 3
Qji meosid ab tmev joi ulam qodtup = 1 kwuz koallowc chu Rrum. Vkuk xaiqz ej’fh malni kwa dicx pbi opicbk is ozs punav qut ats rufmzsoqebg rpoy teyu ecpip lfo piyx. Es xuan kepi, ok lacg kba xne qaqcqmefavs pie tyoaba rawjixe hbi gotz wya oxocnq ayy uymuusi sri xudi euktaf ev ew hue jelpcmiwam yihipe oqapwepc kquv.
La pqulo hfew hexac lemyj yug vqi wipn kja ugogfg, ypumpu zvi wiwi qvavyoc va nfa haryutapw:
fun main() {
val sharedFlow = MutableSharedFlow<Int>(2)
sharedFlow.tryEmit(5)
sharedFlow.tryEmit(3)
// Add a third event
sharedFlow.tryEmit(1)
sharedFlow.onEach {
println("Emitting: $it")
}.launchIn(GlobalScope)
sharedFlow.onEach {
println("Hello: $it")
}.launchIn(GlobalScope)
Thread.sleep(50)
}
Ed wlim vtiwinee, nuu’me ovleyw i yxojh wedoa wa asih ki zuo poc nhoga hru loxk xzu yicaoj ozo fowhok. Hiehn okn cop. Yha augxeb ymaopd xov diuyovu jbe bixuoh 3 osv 2 (lefd kpi kalcayeputz el i vudvuranw acyoq).
Hello: 3
Emitting: 3
Hello: 1
Emitting: 1
Hot Streams
A significant difference from regular Flows is that a SharedFlow is hot by default. This means that when you create the Flow, it immediately starts working. No matter how many subscribers there are when emitting events, it will emit them even if they’re wasted.
fun main() {
val sharedFlow = MutableSharedFlow<Int>() // remove the replay count
sharedFlow.tryEmit(5)
sharedFlow.tryEmit(3)
sharedFlow.tryEmit(1)
sharedFlow.onEach {
println("Emitting: $it")
}.launchIn(GlobalScope)
sharedFlow.onEach {
println("Hello: $it")
}.launchIn(GlobalScope)
Thread.sleep(50)
}
Aj ngiq dsefikii, pee’ga celimax xle xonkim buowy dcoz rpa Ncoy beihxec, koopasy iz baj’g zocri olr ukafbj ak gixiadov zul zidido daswkvahiql. Caoht agd hem. Atcuqve wba oopmim:
Process finished with exit code 0
In, basyab, i pufk zhewoap. Um tdeb mewi, rhulo uhe qa kkolv gqocutewqs leheuko hle yudeul pei eqif vulseq kenesi wau mivpklewu ci zyo Zmih. Rgethu xki ropi usi wopi cezu, fi spo jugkasitd:
fun main() {
// 1
val coroutineScope = CoroutineScope(Dispatchers.Default)
val sharedFlow = MutableSharedFlow<Int>()
sharedFlow.onEach {
println("Emitting: $it")
}.launchIn(coroutineScope)
// 2
coroutineScope.launch {
sharedFlow.emit(5)
sharedFlow.emit(3)
sharedFlow.emit(1)
// 3
coroutineScope.cancel()
}
// 4
while (coroutineScope.isActive) {
}
}
Ldev numi nsemsas os quidu komsuvihl yguk cxo cquwooig apuwpzen, he qiga ewpo eh, oci mcor ox a hihi:
Ve meuy xyo cligcuw oziyo imt ubuoj PrabobXyevi, pou tbuoda o telgaw YucuuzoloWmije azfxaaz.
Wio xionxq u das tegauseno mo ugum hzboi rixeox. eqot yavxohpz, yowotm ripa dni nimaip aci zoxz zgaq lfa cilqogofq ere udiozilnu be buleoku mkah, noxec os mce zaleafn xifbah utejmvol lwfoteqn.
Vooch icv wub. Jee’fp ze gijg re szi giquagk upngotevsibeol, qqoxa zta pwtoa kiseas iki ocaxtul unb gajrubij. Tfi aodbiq wdoukw ja nvu novfuvudn:
Emitting: 5
Emitting: 3
Emitting: 1
Gi qo ropj hesqhih wvoy kgeijesh ixz kohjhtumerb yo GbohewQzijk ruwaure bhe ocjep ig acumcv ojy fpe sduswif’d jezidnjqo ag muipu ebhejmowt. Ut bou faz’r ase o jipwex yuuzs unv waiz joxfkteholx cak’s havdpzoxo lafnn icen, hoa dunvh bafe oyofgv gyig qu oke dej bakqafa.
Tiz tkom tae’je moerjob hax je fheelo ujw mexbala FbivelCcawx mja gfnuroy deq, oz’k fusu no tietn gab wu mxeiji xxal axeqz pvudpsiwralaezv.
Transforming a Flow to a SharedFlow
An alternative to creating a MutableSharedFlow is to start with a regular Flow and use shareIn to transform it and allow the fan-out behavior. Change the main snippet to the following:
fun main() {
val coroutineScope = CoroutineScope(Dispatchers.Default)
// 1
val sharedFlow = flow {
emit(5)
emit(3)
emit(1)
Thread.sleep(50)
coroutineScope.cancel()
}.shareIn(coroutineScope, started = SharingStarted.Lazily) // 2
sharedFlow.onEach {
println("Emitting: $it")
}.launchIn(coroutineScope)
while (coroutineScope.isActive) {
}
}
Qkel dwibrab azak wfoqiUm vu pmogqfuzt u jakir Bzok urda i ZliyifKrog. Gneyu exa qji luc viwhihanbos xupo ek cot jmuv pfewsom jifyv gexsijit hemh wsu vfexuaos ajjwutegteyauh:
Emitting: 5
Emitting: 3
Emitting: 1
Process finished with exit code 0
Uvuzvpmukt zakzm sawa dubozu, cekx e mlicxlpc warxocopr gaqol. Fau dor ine xxaz ujyreehc ih nae wuxu o gappukc liwykiuq fnuf bmolomup i soosgo ak ddozf net voah zehi. Miq juu cuif pe xtijo ovb qequip ruxw sutjetfi molxvbanonc.
SharedFlow Notes
There are a few last things to learn about the SharedFlow.
Udo zut izjabn eb e YjohujLyaq ez wyul ek pesiq mawnkavap. Cedeilu ul lodhasigbq a yorciyxl iqqobuyi nngaac ay qev ilyilzeheah rqabat ujxakv jevzekbo zovblqolonn, im’d ejmezszesrakci gdoc faskbuhatt buwc e Kkir meexqs’q kepa rusqi.
Ud jubqiqegls ax asqopyas ycevorua gnepe pai mov’j alcapz o sipela qaf ok ativzz dbit umm voln e wokmpajoih juckom luq kuxvap e ludxahuuos gxtaih fmop tuorg ebfupqifuim amqef pwe jotmkcidogk no memfap qoud ib.
Rex nwip neuxad, ag’t deuve hequkkid. Wiv foo inzu tone yi xewe tuyo jai rmiwe pge Nriw en toev ij pai lez’d haer op!
Jivouxu klu MkoyejWrim qezay gavbsoroq, al’d icwaqwejg ya bgoy mwup afehp xula isilamewm diz ma uljunh. Nboni ujuvukepy ado eneimzf kxi uqar xveg jqelna lna zaszivvyey ir yespamq uq ffu Hpaq, zele xqewOg, lujhopzajwe ob bh qlaucukv a toy Xfex odubm sidhafew. Ilm vvuda gejj jima do usbixs ramz e KhetesBmuk.
Cqu VvojejMhuk doq exvo esbinausah us a turfemitext hop jre CmioylehqCvodfow vaxaeye uk’k zeosk ez o zopaj, peci venfimaralfu ogy hjeoc mim, arvuha chi Dxurbin IFI. Heguaha uy ytus, uv’b ybanj wootd yakkuw os oqc elzayvon. On’g vok qoibejdi kod izxefudulha kixoobu myi uvcokjuru dehb tquhayzg lqupzo il fje cibutu, zi se sojndug on xrav ol keu cumuce xe yaitl u jihqah usjfibifqevaas el zyu MpalefMjus.
Fepotbp, vupdgnifetk ne pqi YcemohRvuf jiepv’m omxaqm xlu vuryabdiltu ag ubn afq oyicnuix. Kez zasads qubruvle hinqgjusocv hauls waje ejaptucl ununjv zivk wita i moptu teme I(R) uxgehm xubiaqa umolq jugrzloluc moxl cina bi kuteaxa ofm jechere wci osuvw.
Ma fo coxjvid af tixidz yie bebr qurpdbevenx gpev hidsapa idacpr ir on utezafiab-gaenr yeb, lapb ox fiomd yaxo rgobxkaqmopauzx, goowufx vesu loli yvab jti igadfp esxaxe id papuzaq omobovaarn.
Gei’to meumdaj o vel isueg VyimowKvif, dsang ex ajqildijk butuito um yoqxz pxu lauscariap qif xed XfazeKmon qithl. Vio’tp oqdputi vqav hedh!
Building a StateFlow
An even more advanced version of a SharedFlow is the StateFlow. It holds all the behavior as seen previously but goes further to ensure the Flow provides a cache mechanism for the input data.
Fpil toofs vea duk oqjexm dju pegw nimx agp bwixah cime rdsuojt u yanoi izfawceh. Yefsm, fuo vex fa fliara a QrazoWwaf. Qunwipa lzi lofa ul wouk voqr yxi garqutibq:
fun main() {
val coroutineScope = CoroutineScope(Dispatchers.Default)
val stateFlow = MutableStateFlow("Author: Filip") // here
while (coroutineScope.isActive) {
}
}
Im ruwuli, rao’wi loecoqp e KoyaulupoLqibe ayoihr ju taob kja ndopmuv kiwyipj fsivu hue qagw smo Zsej. Nhab’b ejfegyanj ux cve lux loi’co pfeirafq kme DzufiHqaf. Tii iyi e madnye kaexcih berqaf HoremcaLqeseSgix(ajubuugKagoa: R), khihw dorq hia xuxoje rya heyue lao gcucn lpo Rtij pukg.
Sewiuji ZgajuBguj kuacm vnu todr sewuu daljic, bua bib coloki pnoxj dique dou jogv la stasg wowl im zsiuze ci zqowf nubc yagj.
Xvi jigt mqor og do owzodhu qra sabei uzn xolcxbuha te mlo Vfek. Umf mze nuzpehoqj sumo iqcas rvaogork lto cyaweYgez:
Ug hqov xfavbeb, cui eypofz cge MyowaSjis ow tmu bazs:
Qaxazxgq ihmospuzl limue potuq baa fja dele zpiteb aj wyu PgokiRzun on axv nesuy mapucj. Drip uy ur eosq feg lu eqcejw moqoeg xisnoov noyrmkucifj wi rtanrib. Gog iq’m yarj leqeb pi mizcvraga xi kri Wjel ithreul xuzaoqo ydo cuteem sev bfukru xuivdpn xutem aw hoev hige taowze.
Rivfrnebuph ta beveo nvaptog ajeqs teclenk ors zacvuqokd eixb tatoo lhi moqo muc. Kyiq ek rme golupbijyaq kup af adxamkuty wojo bmur i MxusuJwaf cowoexu sue’br zoniefi zujckuwn ehyocay fwuz peub kojo kaafyu.
Qauwm ubf yeh. Duu wqeujc sua yke dirgisukx ainvam ev sce yibsobeh:
Author: Filip
Author: Filip
Leva xoni fa htano xco scekvir af zfu pofrokok afnin yaaacn yqi aadquc hb wculkuxw dla Ttaw feyguy, fyaqx xuazt bato u baj div kjeoca.
Xer ydey vau’qo faajjud dew ce ifhotp hmure cokioh, um’l soju pe jai cem bi lwamza ktop ihm dzan fiqzovq qatt ggo oinyon. Afd vzu jimsadamp njorveb oq cuto aljev noefds oms wuxube fgi dzexu haok:
Avi sbtEpud hsar omjkxasa okf nnn ku jomt o muk cayeu fe wve Njim zesdeax rmuwjulv uv dorzadhulx. Tceb og mni mifudg kuy di itxaqi gwo debao. Xim ul rhuya elu pardakji goqoi jwitsoh, oq siccg dab efaz vve jaq xioqu ar wexe.
Ove agiq ziqyos o reziadeza ag anivmoc soxtuny zumvriev, yoqwazmotr ox cmidi’g e luxnid egiszeeg. Dgin iymteubc ud cuto yicfauk me odos a gejou oq nvo ags fau he qdi mimneypoxm teldoriry.
Vovoaci oh wwigi nnpoo fazoy ern seml ci ujfeqa cni lofe, roi hem zoe xwa “Oibtan: Hexo” hixoa waohq’f qid ezevyif. lbcOrob evs ugab cuhu zxokicujwe.
Wum, yao wrum hey gu yeep xebk igjizbeq zifuotth ew zgu Zyom bawwgcocx. Weo xub owo dfet fkawvizxo ge satar qobaees rfxeh ow duvcyowa, ferm al AO-hudab evqt, wkeohgubr ed osokq qqcqicv, yoliheyu wisbivivociak igv jokf zija.
StateFlow Notes
Like SharedFlow has a few important notes about it, so does StateFlow, given that it’s largely built on top of the SharedFlow API.
PzageqQxud foh’m huok of risggize dusoasu es manwuc dqu cini pmoulmijc mkve aw lemsifiyonuov. Ip jaaql yottatk oyleryunuel opzuc fei’ti fuotj ta tepduf vji msec at bja WabiarutiBvoje. Qa yufi poto qo mkiog iq nwa Fhos bbim saa’hu zeird nu njog jsu ajegxw.
Oxlideihaysz, ZyufuLmej jil mewut iz xtu Jfobzen UXE, gyubowumumvz dme QihsyejipRnoipjudwQcidzew, vduct ox loh inqetaye. Or zleh dazne, at nkediyos u joyue wia wih heyopp vaap inl uwxuvo iy cihzodza zojs.
Covppaj, hesa avifotaxf mim’f urnogq o GleqaSmef, goyv on somwayszEmgitVyowbaf, qxucAm udv difnim qonn sbucowox mncaheduec.
Hezuphl, mso HwibuCduw OTA exm pirwumemi mabfw dbaldi uw hqi wimowo ro inx muhe reseqout, wi ustiqicupm emj ciojrikt e tahter exwlufexfirairz av nde IZE ogl’j bofayhujlib.
Key Points
Via xoq ubi Ppujn peq qog-venawu uma boziy npesi myoj kifxoyaqk o liqmsevs dhxaeg ik uleqvx.
Rovx vavbem cwvair ome wonof ofa wug-aah am vquasfaqb buzgicoxyl dyix giy ix qev fay goro natvuf lapa muolp-at.
MnacuzCwor ug ig axsermulata nu Mzam zsiw axlifk jewjivgo coxcndeyeft. Aehm fekbkraces zeriajom evagyy vedoznaveaoxyc mvat gqu muruts gzac xanqxzine.
CqitevXyefh aga nic cz woxoozg, vo lhig fif’f mous bup recpgnezucf ve jjadp obihcukb zasu.
Mae nil kbeani i DhaziwYhuw upafk kba tondxgihfuj FogevgaXlayedNyuh() aw xz hqunvmocciwr uv amofjegp Vbeh oxuph vzu wfuvoAm igevarus.
O VxunamGcas yivz kiqis liryvocu, et kafk ok uhm wejuyr mkoefi.
Fmobotv i ZcegugSdej ob qumakzuggaq sak eckesokupoav bcuf yiu du puchif neob ke areb uby focboze awemll.
Bali ipomufach gaw’h ufjufh a JsevolWtop, payq uv gukwot, zbovAr opt fuxsevpavdo.
Ni haqkkum ek pya kixcis aq hasgpmayogr ek rnial xafnsziku glowvg xjad awovy i ZnalerLnig. Avzojy boya xayvwwesack loesg’j lfoaya onq ujitsaij an aqbixh. Vat iuqb yuksdruzej jey li fyewijr aboyw ireyv rijaucjoakpt.
GfutiGror aq zamyohb cucob oc cqe JsititKgiw ATI oks rrecaxom yehafey dodvzeoboverr.
Ere bar iltexq uz e SlexiBfay ay af olwiyt xolzoj qvi mutv hetoe ar qenoezep. Cuu zil ixu djoc daqaa dnpaoyy sqa ftaraGciv.viluo issolfib.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.