{"id":1986,"date":"2023-08-03T22:00:45","date_gmt":"2023-08-03T13:00:45","guid":{"rendered":"http:\/\/batmask.dothome.co.kr\/?p=1986"},"modified":"2025-09-07T11:40:43","modified_gmt":"2025-09-07T02:40:43","slug":"kotlin-flow-part-2-shared-flow-state-flow","status":"publish","type":"post","link":"http:\/\/batmask.net\/index.php\/2023\/08\/03\/1986\/","title":{"rendered":"Kotlin : Flow Part.2 (Shared Flow, State Flow)"},"content":{"rendered":"\n<p> \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Flow\ub85c \uc77d\uc5b4\uc624\ub294 \ub370\uc774\ud130\ub294 UI\uc5d0 \uc0ac\uc6a9\ub420 \uc2dc, \uc8fc\ub85c viewmodel\uc5d0 \uc800\uc7a5\ud558\ub294 livedata\ud615\ud0dc\ub85c \ubcc0\ud658\ud574\uc11c \uc0ac\uc6a9\ud558\uac8c \ub41c\ub2e4. UI \uc5c5\ub370\uc774\ud2b8\ub294 observable\ud55c \ub370\uc774\ud130\ub97c \ud544\uc694\ub85c \ud558\uae30 \ub54c\ubb38\uc774\ub2e4. Flow\ub294 cold stream\uc774\uae30 \ub54c\ubb38\uc5d0 observable\ud55c \ud615\ud0dc\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4. \uc635\uc800\ubc84 \ud328\ud134\uc740 \ub2e4\ub978\ub9d0\ub85c \ubc1c\ud589-\uad6c\ub3c5(Publisher-Subscriber) \ubaa8\ub378\ub85c \ub9d0\ud558\uae30\ub3c4 \ud558\ub294\ub370, \ubc1c\ud589\ud558\ub294 \ucabd\uc774 \ub370\uc774\ud130\uac00 \ubc14\ub014 \ub54c\ub9c8\ub2e4 \uad6c\ub3c5\uc790\ub4e4\uc5d0\uac8c \ube0c\ub85c\ub4dc \uce90\uc2a4\ud305\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0, hot stream \ud615\ud0dc\ub85c \uad6c\ud604\ub418\uc5b4\uc57c \ud55c\ub2e4. \ub9cc\uc57d, livedata\ub97c \uc0ac\uc6a9\ud558\uc9c0 \uc54a\ub294\ub2e4\uba74? Flow\ub9cc\uc73c\ub85c\ub294 \ubc29\ubc95\uc774 \uc5c6\ub2e4.<\/p>\n\n\n\n<p> \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c livedata\ub294 lifecycle\uc744 \uac16\ub294 \uacf3\uc5d0\uc11c\ub9cc \uc0ac\uc6a9\uac00\ub2a5 \ud558\uae30 \ub54c\ubb38\uc5d0, \ub370\uc774\ud130\ub9cc \ub2e4\ub8e8\ub294 \ub3c4\uba54\uc778 \ub808\uc774\uc5b4\uc5d0\uc11c \uc0ac\uc6a9\ud558\uae30 \ubd80\uc801\ud569\ud558\ub2e4. \uadf8\ub7fc\uc5d0\ub3c4 \uac1c\ubc1c\uc790\ub4e4\uc774 \ud544\uc694\ub85c \ud588\uace0, livedata\uc5c6\uc774 \uc9c0\uc6d0\ud558\uae30 \uc704\ud55c Flow\uac00 \ud544\uc694\ud588\ub2e4. <\/p>\n\n\n\n<p> \uc5b4\ub514\uae4c\uc9c0\ub098 \uc548\ub4dc\ub85c\uc774\ub4dc \uce21\uba74\uc5d0\uc11c \uc774\uc640\uac19\uc740 \ud544\uc694\uc5d0 \uc758\ud574 \ub098\uc628\uac83\uc774 Shared Flow\uc640 State Flow\uc774\ub2e4. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Shared Flow<\/h4>\n\n\n\n<p>  Kotlin\uc758 \ucf54\ub8e8\ud2f4\uc5d0\uc11c \ubc1c\ud589-\uad6c\ub3c5 \ubaa8\ub378\uc740 \ucc98\uc74c\uc5d0 BroadcastChannel\ub85c \uad6c\ud604\ub418\uc5c8\uc5c8\ub2e4. \uadf8\ub7ec\ub098 \ubc84\uc804\uc774 \uc62c\ub77c\uac00\uba74\uc11c \ub354 \ub098\uc740 Shared Flow\ub85c \ub300\uccb4\ub418\uc5c8\ub2e4. Shared Flow\ub294 RxJava\uc758 Subject\uc5d0 \ud574\ub2f9\ud55c\ub2e4\uace0 \ud55c\ub2e4. RxJava\ub97c \ub0b4\uac00 \uc548\uc368\ubd10\uc11c \ubaa8\ub974\uaca0\uc9c0\ub9cc, Shared Flow\uc758 \ub4f1\uc7a5\uc774 Reactive programming\uc758 \uc601\ud5a5\ub3c4 \uc788\uc5c8\ub358\uac70 \uac19\ub2e4. <\/p>\n\n\n\n<p>\ub2f9\uc5f0\ud558\uac8c\ub3c4 \uc774\ubca4\ud2b8\uc758 \ube0c\ub85c\ub4dc\uce90\uc2a4\ud305\uc5d0 \ucd5c\uc801\ud654\ub41c \ud615\ud0dc\uc774\ub2e4. <\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"720\" height=\"223\" src=\"http:\/\/batmask.dothome.co.kr\/wordpress\/wp-content\/uploads\/2023\/08\/shared_flow01.webp\" alt=\"\" class=\"wp-image-1990\"\/><\/figure>\n<\/div>\n\n\n<p>sharedFlow\uc758 \ud615\ud0dc\ub97c \ub2e4\uc774\uc5b4\uadf8\ub7a8\uc73c\ub85c \ubcf4\uc5ec\uc8fc\ub294 \uc704 \uadf8\ub9bc\uc740 <a href=\"https:\/\/elizarov.medium.com\/shared-flows-broadcast-channels-899b675e805c\">Shared flows, broadcast channels<\/a> \uc5d0\uc11c \uac00\uc838\uc654\ub2e4. <\/p>\n\n\n\n<p> SharedFlow\ub294 emit\uacfc collect\uac00 \ube44\ub3d9\uae30\uc801\uc73c\ub85c \uc791\ub3d9\ud558\ubbc0\ub85c, \ub2f9\uc5f0\ud558\uac8c\ub3c4 back-pressure\uac00 \uc874\uc7ac\ud55c\ub2e4. back-pressure\ub780, emit \uc18d\ub3c4\uac00 collect \uc18d\ub3c4\ubcf4\ub2e4 \ube60\ub97c \uacbd\uc6b0, \ub370\uc774\ud130\uac00 \ubc00\ub824\uc11c \ubc84\ud37c\uc624\ubc84\ud50c\ub85c\uc6b0\uac00 \ubc1c\uc0dd\ud558\ub294\uac78 \ub9d0\ud55c\ub2e4. Shared flow\ub294 \ubc84\ud37c\uac00 \uac00\ub4dd\ucc28\uba74, emit\uc744 \uba48\ucd98\ub2e4\uace0 \ud55c\ub2e4. \ub610\ud55c BufferOverflow \ud30c\ub77c\ubbf8\ud130\ub85c \uc870\uc815\uc774 \uac00\ub2a5\ud558\ub2e4.<\/p>\n\n\n\n<p> \uac04\ub2e8\ud55c \uc608\uc81c\ub97c \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class SharedFlowClass() {\n    private val _mutableSharedFlow =\n        MutableSharedFlow&lt;String>()\n    val sharedFlow: SharedFlow&lt;String>\n        get() = _mutableSharedFlow\n\n    suspend fun broadcast() {\n        delay(1000)\n        _mutableSharedFlow.emit(\"Message1\")\n        _mutableSharedFlow.emit(\"Message2\")\n\n    }\n}\n\nfun main(args: Array&lt;String>): Unit = runBlocking {\n\n    val sharedFlowClass = SharedFlowClass()\n\n    launch {\n        sharedFlowClass.sharedFlow.collect {\n        println(\"#1 received $it\")\n    }\n    }\n    launch {\n        sharedFlowClass.sharedFlow.collect {\n            println(\"#2 received $it\")\n        }\n    }\n\n    sharedFlowClass.broadcast()\n    println(\"\\nend of main\")\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">SharedFlowClass<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">private<\/span><span style=\"color: #ADBAC7\"> val <\/span><span style=\"color: #F69D50\">_mutableSharedFlow<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">MutableSharedFlow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">&gt;()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val <\/span><span style=\"color: #F69D50\">sharedFlow<\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">SharedFlow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">get<\/span><span style=\"color: #ADBAC7\">() = _mutableSharedFlow<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    suspend fun <\/span><span style=\"color: #DCBDFB\">broadcast<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">delay<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">1000<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        _mutableSharedFlow.<\/span><span style=\"color: #DCBDFB\">emit<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;Message1&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        _mutableSharedFlow.<\/span><span style=\"color: #DCBDFB\">emit<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;Message2&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">fun <\/span><span style=\"color: #DCBDFB\">main<\/span><span style=\"color: #ADBAC7\">(args: Array<\/span><span style=\"color: #F47067\">&lt;<\/span><span style=\"color: #ADBAC7\">String<\/span><span style=\"color: #F47067\">&gt;<\/span><span style=\"color: #ADBAC7\">): Unit <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> runBlocking {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val sharedFlowClass <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">SharedFlowClass<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        sharedFlowClass.sharedFlow.collect {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;#1 received $it&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        sharedFlowClass.sharedFlow.collect {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;#2 received $it&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    sharedFlowClass.<\/span><span style=\"color: #DCBDFB\">broadcast<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #F47067\">\\n<\/span><span style=\"color: #96D0FF\">end of main&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>MutableSharedFlow\ub294 \uac00\uc7a5 \uae30\ubcf8\uc801\uc778 SharedFlow\uc758 \uad6c\ud604\uc774\ub2e4. \ud074\ub798\uc2a4\uc5d0\uc11c MutableSharedFlow\ub97c \uc815\uc758\ud558\uace0 \uc77d\uae30\uc804\uc6a9\uc73c\ub85c SharedFlow\ub9cc \ub178\ucd9c\uc2dc\ucf1c\uc11c emit\uc740 \uc774 \ud074\ub798\uc2a4\uc5d0\uc11c\ub9cc \uac00\ub2a5\ud558\ub3c4\ub85d \ub9cc\ub4e4\uc5c8\ub2e4. \uba54\uc778\ud568\uc218\uc5d0\uc11c\ub294 \ub450 \uac1c\uc758 \ucf54\ub8e8\ud2f4\uc744 \ub9cc\ub4e4\uc5b4 collect\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub450\uac1c\uc758 \uad6c\ub3c5\uc790\ub97c \ub9cc\ub4e4\uc5c8\ub2e4. sharedFlowClass.broadcast()\ub294 \uc5ec\uc720\uc788\uac8c \ub098\uc911\uc5d0 \uc2e4\ud589\ud558\uc5ec \uad6c\ub3c5\uc774 \uc81c\ub300\ub85c \ub3d9\uc791\ud558\uac8c \ud558\uc600\ub2e4. \uacb0\uacfc\ub97c \ubcf4\uba74, <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#1 received Message1\n#2 received Message1\n#1 received Message2\n#2 received Message2\n\nend of main<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ADBAC7\">#<\/span><span style=\"color: #6CB6FF\">1<\/span><span style=\"color: #ADBAC7\"> received Message1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">#<\/span><span style=\"color: #6CB6FF\">2<\/span><span style=\"color: #ADBAC7\"> received Message1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">#<\/span><span style=\"color: #6CB6FF\">1<\/span><span style=\"color: #ADBAC7\"> received Message2<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">#<\/span><span style=\"color: #6CB6FF\">2<\/span><span style=\"color: #ADBAC7\"> received Message2<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">end <\/span><span style=\"color: #F47067\">of<\/span><span style=\"color: #ADBAC7\"> main<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uad6c\ub3c5 \ucf54\ub8e8\ud2f4\uc5d0\uc11c \uac01\uac01 \uba54\uc138\uc9c0\ub97c \uc811\uc218\ud55c\uac78 \ud655\uc778\uac00\ub2a5\ud558\ub2e4. \uc8fc\uc758\ud560\uc810\uc740, \ud504\ub85c\uc138\uc2a4\uac00 \ub05d\ub098\uc9c0 \uc54a\ub294\ub2e4\ub294 \uc810\uc774\ub2e4. runBlocking\uc774 \ucf54\ub8e8\ud2f4\uc758 \uc885\ub8cc\ub97c \ub300\uae30\uc911\uc778\ub370, SharedFlow\ub294 \uc885\ub8cc\uac00 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \ubb34\ud55c \ub300\uae30\uc911\uc778 \uad6c\ub3c5 \ucf54\ub8e8\ud2f4\uc774 \ub05d\ub098\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc774\ub2e4. SharedFlow\ub294 \uc885\ub8cc\uac00 \uc548\ub418\uc9c0\ub9cc, \uad6c\ub3c5 \ucf54\ub8e8\ud2f4\uc744 cancel\ud558\uc5ec \uc885\ub8cc\uac00 \uac00\ub2a5\ud558\ub2e4. \uba54\uc778\ud568\uc218\ub97c \ub2e4\uc74c\uacfc \uac19\uc774 \ubcc0\ud615\ud558\uc5ec \uc885\ub8cc\uc2dc\ucf1c\ubcf4\uc790.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>fun main(args: Array&lt;String>): Unit = runBlocking {\n\n    val sharedFlowClass = SharedFlowClass()\n\n    val job1 = launch {\n        sharedFlowClass.sharedFlow.collect {\n        println(\"#1 received $it\")\n        }\n    }\n\n    val job2 = launch {\n        sharedFlowClass.sharedFlow.collect {\n            println(\"#2 received $it\")\n        }\n    }\n\n    sharedFlowClass.broadcast()\n    delay(1000)\n    job1.cancelAndJoin()\n    job2.cancelAndJoin()\n    println(\"\\nend of main\")\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #ADBAC7\">fun <\/span><span style=\"color: #DCBDFB\">main<\/span><span style=\"color: #ADBAC7\">(args: Array<\/span><span style=\"color: #F47067\">&lt;<\/span><span style=\"color: #ADBAC7\">String<\/span><span style=\"color: #F47067\">&gt;<\/span><span style=\"color: #ADBAC7\">): Unit <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> runBlocking {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val sharedFlowClass <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">SharedFlowClass<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val job1 <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        sharedFlowClass.sharedFlow.collect {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;#1 received $it&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val job2 <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        sharedFlowClass.sharedFlow.collect {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;#2 received $it&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    sharedFlowClass.<\/span><span style=\"color: #DCBDFB\">broadcast<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">delay<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">1000<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    job1.<\/span><span style=\"color: #DCBDFB\">cancelAndJoin<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    job2.<\/span><span style=\"color: #DCBDFB\">cancelAndJoin<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #F47067\">\\n<\/span><span style=\"color: #96D0FF\">end of main&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uc2e4\ud589\uc2dc\ucf1c \ubcf4\uba74, \uc815\uc0c1 \uc885\ub8cc\ub428\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4. <\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Shared flow\uac00 \uc790\uc8fc \uc4f0\uc774\ub294 \uac70 \uac19\uc9c0 \uc54a\uc9c0\ub9cc, Shared Flow\uc758 \ud55c \ud615\ud0dc\uc778 State Flow\ub294 \ub9e4\uc6b0 \uc720\uc6a9\ud558\uac8c \uc4f0\uc778\ub2e4. State Flow\ub97c \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">State Flow<\/h4>\n\n\n\n<p> State flow\ub294 Shared flow\uc758 \ud55c \ud615\ud0dc\uc774\ub2e4. \ubc14\ub85c \uc704\uc5d0\uc11c back-pressure\uc5d0 \ub300\ud574 \ub2e4\ub918\uc5c8\ub294\ub370, buffer overflow\ub97c \ud574\uacb0\ud558\ub294 \uc804\ub7b5\uc911 \ud558\ub098\ub85c, \uc624\ub798\ub41c \ub370\uc774\ud130\ub97c \ub4dc\ub86d\ud574 \ubc84\ub9ac\uace0 \uc0c8 \ub370\uc774\ud130\ub97c \ub123\ub294 \ubc29\ubc95\uc774 \uc788\ub2e4. State flow\ub294 \uc774\ub7f0\uc2dd\uc73c\ub85c \ud56d\uc0c1 \ucd5c\uc2e0\uc758 \ub370\uc774\ud130, \uace7 state\ub9cc \uc720\uc9c0\ud55c\ub2e4. <\/p>\n\n\n\n<p>State Flow\ub294 \uac12\uc758 \uc0c1\ud0dc\ubcc0\ud654\ub97c \ube0c\ub85c\ub4dc\uce90\uc2a4\ud2b8\ud558\ub294 Shared Flow\ub85c \ud574\uc11d\ud560 \uc218 \uc788\ub2e4. \uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c \uc774\uac8c \uc911\uc694\ud55c \uc774\uc720\ub294, state flow\uac00 livedata\ucc98\ub7fc \uc791\ub3d9\ud558\uae30 \ub54c\ubb38\uc5d0, \uc548\ub4dc\ub85c\uc774\ub4dc\uc758 lifecycle\uc5d0 \uad6c\uc560\ubc1b\uc9c0 \uc54a\uace0 \ub3c4\uba54\uc778 \ub808\uc774\uc5b4\uae4c\uc9c0 \uc5bc\ub9cc\ub4e0\uc9c0 \uc0ac\uc6a9\uac00\ub2a5\ud558\ub2e4. <\/p>\n\n\n\n<p>\uac04\ub2e8\ud55c \uc608\uc81c\ub97c \uc0b4\ud3b4\ubcf4\uc790.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class StateFlowClass() {\n    private val _mutableStateFlow = MutableStateFlow&lt;String>(\"hello? Initial state\")\n    val stateFlow: StateFlow&lt;String>\n        get() = _mutableStateFlow\n\n    suspend fun changeState(msg: String) {\n        _mutableStateFlow.value = msg\n    }\n}\n\nfun main(args: Array&lt;String>): Unit = runBlocking {\n\n    val stateFlowClass = StateFlowClass()\n\n    launch {\n        stateFlowClass.stateFlow.collect {\n            println(\"state : $it\")\n        }\n    }\n\n    delay(1000)\n    stateFlowClass.changeState(\"I'm solid state\")\n    delay(1000)\n    stateFlowClass.changeState(\"I'm liquid state\")\n    delay(1000)\n    stateFlowClass.changeState(\"I'm gas state\")\n    println(\"\\nend of main\")\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">StateFlowClass<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">private<\/span><span style=\"color: #ADBAC7\"> val <\/span><span style=\"color: #F69D50\">_mutableStateFlow<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">MutableStateFlow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">&gt;(<\/span><span style=\"color: #96D0FF\">&quot;hello? Initial state&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val <\/span><span style=\"color: #F69D50\">stateFlow<\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">StateFlow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #DCBDFB\">get<\/span><span style=\"color: #ADBAC7\">() = _mutableStateFlow<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    suspend fun <\/span><span style=\"color: #DCBDFB\">changeState<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #F69D50\">msg<\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">String<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        _mutableStateFlow.value <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> msg<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">fun <\/span><span style=\"color: #DCBDFB\">main<\/span><span style=\"color: #ADBAC7\">(args: Array<\/span><span style=\"color: #F47067\">&lt;<\/span><span style=\"color: #ADBAC7\">String<\/span><span style=\"color: #F47067\">&gt;<\/span><span style=\"color: #ADBAC7\">): Unit <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> runBlocking {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val stateFlowClass <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">StateFlowClass<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        stateFlowClass.stateFlow.collect {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;state : $it&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">delay<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">1000<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    stateFlowClass.<\/span><span style=\"color: #DCBDFB\">changeState<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;I&#39;m solid state&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">delay<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">1000<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    stateFlowClass.<\/span><span style=\"color: #DCBDFB\">changeState<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;I&#39;m liquid state&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">delay<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #6CB6FF\">1000<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    stateFlowClass.<\/span><span style=\"color: #DCBDFB\">changeState<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;I&#39;m gas state&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #DCBDFB\">println<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #96D0FF\">&quot;<\/span><span style=\"color: #F47067\">\\n<\/span><span style=\"color: #96D0FF\">end of main&quot;<\/span><span style=\"color: #ADBAC7\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>\uba54\uc778\uc5d0\uc11c collect\ub97c \ud558\uace0 \uac12\uc744 1\ucd08 \uac04\uaca9\uc73c\ub85c \uacc4\uc18d \ubc14\uafd4\uc8fc\uace0 \uc788\ub2e4. \uc8fc\uc758\ud560 \uc810\uc740, changeState()\ub97c \ubcf4\uba74, emit\uc744 \uc4f0\uc9c0\uc54a\uace0, value\uc758 \uac12\uc744 \ubc14\uafd4\uc8fc\ub294 \uac83\uc744 \ubcfc \uc218 \uc788\ub2e4. \ub2e8\uc77c \uac12\uc5d0 \ub300\ud574 \ubcc0\uacbd\ub9cc \ud574\uc8fc\ub294 \uac83\uc774\ub2e4. \ub610\ud55c, livedata\uc640 \ub2e4\ub974\uac8c \ucd08\uae30\uac12\uc774 \ud544\uc694\ud55c \uac83\ub3c4 \uc54c \uc218 \uc788\ub2e4. \uacb0\uacfc\ub97c \ubcf4\uba74, <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(1 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>state : hello? Initial state\nstate : I'm solid state\nstate : I'm liquid state\n\nend of main\nstate : I'm gas state<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F69D50\">state<\/span><span style=\"color: #ADBAC7\"> : hello<\/span><span style=\"color: #F47067\">?<\/span><span style=\"color: #ADBAC7\"> Initial state<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">state <\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #6CB6FF\">I<\/span><span style=\"color: #96D0FF\">&#39;m solid stat<\/span><span style=\"color: #FF938A; font-style: italic\">e<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F69D50\">state<\/span><span style=\"color: #ADBAC7\"> : <\/span><span style=\"color: #6CB6FF\">I<\/span><span style=\"color: #96D0FF\">&#39;m liquid stat<\/span><span style=\"color: #FF938A; font-style: italic\">e<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">end <\/span><span style=\"color: #F47067\">of<\/span><span style=\"color: #ADBAC7\"> main<\/span><\/span>\n<span class=\"line\"><span style=\"color: #F69D50\">state<\/span><span style=\"color: #ADBAC7\"> : <\/span><span style=\"color: #6CB6FF\">I<\/span><span style=\"color: #96D0FF\">&#39;m gas stat<\/span><span style=\"color: #FF938A; font-style: italic\">e<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p> \uc2e4\ud589\uc2dc, delay(1000)\uc5d0 \ub530\ub77c 1\ucd08\uac04\uaca9\uc73c\ub85c \uc0c1\ud0dc\uac00 \ubc14\ub00c\ub294\uac78 \ud655\uc778 \ud560 \uc218 \uc788\ub2e4. \ub610\ud55c, SharedFlow\uc640 \ub3d9\uc77c\ud558\uac8c, \ud504\ub85c\uc138\uc2a4\uac00 \uc885\ub8cc\ub418\uc9c0 \uc54a\ub294\ub2e4. StateFlow\ub3c4 \uc885\ub8cc\uac00 \uc5c6\uae30 \ub54c\ubb38\uc774\ub2e4. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\">State Flow in Android <\/h4>\n\n\n\n<p>\uacf5\uc2dd \uac00\uc774\ub4dc\uc5d0 \ub098\uc628 \uc608\uc81c\ub97c \ucca8\ubd80\ud574 \ubcf8\ub2e4. <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class LatestNewsViewModel(\n    private val newsRepository: NewsRepository\n) : ViewModel() {\n\n    \/\/ Backing property to avoid state updates from other classes\n    private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList()))\n    \/\/ The UI collects from this StateFlow to get its state updates\n    val uiState: StateFlow&lt;LatestNewsUiState> = _uiState\n\n    init {\n        viewModelScope.launch {\n            newsRepository.favoriteLatestNews\n                \/\/ Update View with the latest favorite news\n                \/\/ Writes to the value property of MutableStateFlow,\n                \/\/ adding a new element to the flow and updating all\n                \/\/ of its collectors\n                .collect { favoriteNews ->\n                    _uiState.value = LatestNewsUiState.Success(favoriteNews)\n                }\n        }\n    }\n}\n\n\/\/ Represents different states for the LatestNews screen\nsealed class LatestNewsUiState {\n    data class Success(val news: List&lt;ArticleHeadline>): LatestNewsUiState()\n    data class Error(val exception: Throwable): LatestNewsUiState()\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">LatestNewsViewModel<\/span><span style=\"color: #ADBAC7\">(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">private<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">val<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">newsRepository<\/span><span style=\"color: #ADBAC7\">: <\/span><span style=\"color: #F69D50\">NewsRepository<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">) : <\/span><span style=\"color: #F69D50\">ViewModel<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #768390\">\/\/ Backing property to avoid state updates from other classes<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">private<\/span><span style=\"color: #ADBAC7\"> val <\/span><span style=\"color: #F69D50\">_uiState<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">MutableStateFlow<\/span><span style=\"color: #ADBAC7\">(LatestNewsUiState.<\/span><span style=\"color: #DCBDFB\">Success<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #DCBDFB\">emptyList<\/span><span style=\"color: #ADBAC7\">()))<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #768390\">\/\/ The UI collects from this StateFlow to get its state updates<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    val <\/span><span style=\"color: #F69D50\">uiState<\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">StateFlow<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">LatestNewsUiState<\/span><span style=\"color: #ADBAC7\">&gt; <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> _uiState<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    init {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        viewModelScope.launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            newsRepository.favoriteLatestNews<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ Update View with the latest favorite news<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ Writes to the value property of MutableStateFlow,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ adding a new element to the flow and updating all<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ of its collectors<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                .collect { favoriteNews <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    _uiState.value <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> LatestNewsUiState.<\/span><span style=\"color: #DCBDFB\">Success<\/span><span style=\"color: #ADBAC7\">(favoriteNews)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #768390\">\/\/ Represents different states for the LatestNews screen<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">sealed <\/span><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">LatestNewsUiState<\/span><span style=\"color: #ADBAC7\"> {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    data <\/span><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">Success<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #F69D50\">val<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">news<\/span><span style=\"color: #ADBAC7\">: <\/span><span style=\"color: #F69D50\">List<\/span><span style=\"color: #ADBAC7\">&lt;<\/span><span style=\"color: #F69D50\">ArticleHeadline<\/span><span style=\"color: #ADBAC7\">&gt;): <\/span><span style=\"color: #F69D50\">LatestNewsUiState<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F69D50\">data<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">Error<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #F69D50\">val<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">exception<\/span><span style=\"color: #ADBAC7\">: <\/span><span style=\"color: #F69D50\">Throwable<\/span><span style=\"color: #ADBAC7\">): <\/span><span style=\"color: #F69D50\">LatestNewsUiState<\/span><span style=\"color: #ADBAC7\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p> repository\ub85c\ubd80\ud130 \uc77d\uc5b4\uc624\ub294 favoriteLatestNews\ub3c4 Flow\ub85c \uc77d\uc5b4\uc624\ub294\uac8c \ubcf4\uc778\ub2e4. repository\uc5d0\uc11c emit\ub418\uc5b4 \ub274\uc2a4\uac00 \uc5c5\ub370\uc774\ud2b8 \ub418\uba74, StateFlow\uc778 uiState\uc758 value\uc5d0 \ub274\uc2a4 \ud5e4\ub4dc\ub77c\uc778\uc744 \uc5c5\ub370\uc774\ud2b8\ud55c\ub2e4. UI\uc5d0\uc11c \uac00\uc838\uac00\ub294 \ucf54\ub4dc\ub3c4 \uc0b4\ud3b4\ubcf4\uba74, <\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers\" data-code-block-pro-font-family=\"Code-Pro-Roboto-Mono.ttf\" style=\"font-size:clamp(14px, .875rem, 21px);font-family:Code-Pro-Roboto-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#adbac7;--cbp-line-number-width:calc(2 * 0.6 * .875rem);line-height:clamp(20px, 1.25rem, 30px);--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span style=\"display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#22272e\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"54\" height=\"14\" viewBox=\"0 0 54 14\"><g fill=\"none\" fill-rule=\"evenodd\" transform=\"translate(1 1)\"><circle cx=\"6\" cy=\"6\" r=\"6\" fill=\"#FF5F56\" stroke=\"#E0443E\" stroke-width=\".5\"><\/circle><circle cx=\"26\" cy=\"6\" r=\"6\" fill=\"#FFBD2E\" stroke=\"#DEA123\" stroke-width=\".5\"><\/circle><circle cx=\"46\" cy=\"6\" r=\"6\" fill=\"#27C93F\" stroke=\"#1AAB29\" stroke-width=\".5\"><\/circle><\/g><\/svg><\/span><span role=\"button\" tabindex=\"0\" style=\"color:#adbac7;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>class LatestNewsActivity : AppCompatActivity() {\n    private val latestNewsViewModel = \/\/ getViewModel()\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        ...\n        \/\/ Start a coroutine in the lifecycle scope\n        lifecycleScope.launch {\n            \/\/ repeatOnLifecycle launches the block in a new coroutine every time the\n            \/\/ lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.\n            repeatOnLifecycle(Lifecycle.State.STARTED) {\n                \/\/ Trigger the flow and start listening for values.\n                \/\/ Note that this happens when lifecycle is STARTED and stops\n                \/\/ collecting when the lifecycle is STOPPED\n                latestNewsViewModel.uiState.collect { uiState ->\n                    \/\/ New value received\n                    when (uiState) {\n                        is LatestNewsUiState.Success -> showFavoriteNews(uiState.news)\n                        is LatestNewsUiState.Error -> showError(uiState.exception)\n                    }\n                }\n            }\n        }\n    }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki github-dark-dimmed\" style=\"background-color: #22272e\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #F47067\">class<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">LatestNewsActivity<\/span><span style=\"color: #ADBAC7\"> : <\/span><span style=\"color: #F69D50\">AppCompatActivity<\/span><span style=\"color: #ADBAC7\">() {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">private<\/span><span style=\"color: #ADBAC7\"> val <\/span><span style=\"color: #F69D50\">latestNewsViewModel<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F47067\">=<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #768390\">\/\/ getViewModel()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    <\/span><span style=\"color: #F47067\">override<\/span><span style=\"color: #ADBAC7\"> fun <\/span><span style=\"color: #DCBDFB\">onCreate<\/span><span style=\"color: #ADBAC7\">(<\/span><span style=\"color: #F69D50\">savedInstanceState<\/span><span style=\"color: #F47067\">:<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #F69D50\">Bundle<\/span><span style=\"color: #F47067\">?<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #F47067\">...<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        <\/span><span style=\"color: #768390\">\/\/ Start a coroutine in the lifecycle scope<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        lifecycleScope.launch {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #768390\">\/\/ repeatOnLifecycle launches the block in a new coroutine every time the<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #768390\">\/\/ lifecycle is in the STARTED state (or above) and cancels it when it&#39;s STOPPED.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            <\/span><span style=\"color: #DCBDFB\">repeatOnLifecycle<\/span><span style=\"color: #ADBAC7\">(Lifecycle.State.<\/span><span style=\"color: #6CB6FF\">STARTED<\/span><span style=\"color: #ADBAC7\">) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ Trigger the flow and start listening for values.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ Note that this happens when lifecycle is STARTED and stops<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                <\/span><span style=\"color: #768390\">\/\/ collecting when the lifecycle is STOPPED<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                latestNewsViewModel.uiState.collect { uiState <\/span><span style=\"color: #F47067\">-&gt;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    <\/span><span style=\"color: #768390\">\/\/ New value received<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    <\/span><span style=\"color: #DCBDFB\">when<\/span><span style=\"color: #ADBAC7\"> (uiState) {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                        is LatestNewsUiState.Success <\/span><span style=\"color: #F47067\">-&gt;<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">showFavoriteNews<\/span><span style=\"color: #ADBAC7\">(uiState.news)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                        is LatestNewsUiState.Error <\/span><span style=\"color: #F47067\">-&gt;<\/span><span style=\"color: #ADBAC7\"> <\/span><span style=\"color: #DCBDFB\">showError<\/span><span style=\"color: #ADBAC7\">(uiState.exception)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">                }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #ADBAC7\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>repeatOnLifecycle()\uc744 \uc4f0\uace0\uc788\ub2e4. \uc8fc\uc11d\uc5d0\ub3c4 \uc368\uc788\uc9c0\ub9cc, \uc774\uac83\uc740 \uc778\uc790\ub85c \ub118\uaca8\uc900 Lifecycle\uc744 \ub530\ub77c\uc11c \ucf54\ub8e8\ud2f4\uc744 \uc0dd\uc131\ud558\uace0, \ubc97\uc5b4\ub098\uba74 cancel\uc2dc\ucf1c \uba48\ucd94\uace0, \ub2e4\uc2dc \ub4e4\uc5b4\uc624\uba74 \ucf54\ub8e8\ud2f4\uc744 \uc0c8\ub85c \uc0dd\uc131\ud55c\ub2e4. Lifecycle\uc744 \uc790\ub3d9\uc73c\ub85c \ub530\ub77c\uac00\ub294 Livedata\uc640\uc758 \ucc28\ubcc4\uc810\uc778\ub370, \ucf54\ub8e8\ud2f4\uc740 \uc0dd\uc131\uacfc \uc885\ub8cc\uc758 CoroutineScope\ub9cc \uc874\uc7ac\ud558\uace0 Lifecycle\uc758 state\ub294 \uc0c1\uad00\uc774 \uc5c6\uae30 \ub54c\ubb38\uc5d0 \uc774\ub7f0 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud55c\ub2e4. \uc774\ub807\uac8c \ud558\ub294\uac74 \ub2f9\uc5f0\ud558\uac8c\ub3c4 UI\uac00 \ubcf4\uc5ec\uc9c8 \ub54c\ub9cc \uc758\ubbf8\uac00 \uc788\uace0, UI \ucef4\ud3ec\ub10c\ud2b8\ub4e4\ub3c4 \uc720\ud6a8\ud558\uae30 \ub54c\ubb38\uc774\ub2e4. <\/p>\n\n\n\n<p>StateFlow\ub97c collect\ud558\ub294\uac74 \uac04\ub2e8\ud558\uace0 \uc77c\ubc18\uc801\uc778 Flow\ub791 \ub3d9\uc77c\ud558\uac8c \ubcf4\uc778\ub2e4. <\/p>\n\n\n\n<h4 class=\"wp-block-heading\"> \uc77c\ub2e8 \ub9c8\ubb34\ub9ac<\/h4>\n\n\n\n<p> \ubb54\uac00&#8230; \ub354 \ub9ce\uc740\uac8c \uc788\uc5c8\ub358\uac70 \uac19\uc740\ub370, \uc774\uc815\ub3c4\uba74 \uae30\ubcf8\uc801\uc778\uac74 \ub2e4\ub8ec\uac70 \uac19\uc544\uc11c \uc77c\ub2e8 \uc5ec\uae30\uc11c \ub9c8\ubb34\ub9ac \uc9d3\uaca0\ub2e4. \ubcf5\uc7a1\ud55c \uacbd\uc6b0\ub97c \ub2e4 \ub098\uc5f4\ud558\uae30\ub3c4 \ud798\ub4e4\uace0, \ub098\ub3c4 \uacaa\uc5b4\ubd10\uc57c \uc544\ub294\uac70\uace0, \uadf8\ub7f0 \uac01\uac01\uc758 \ucf00\uc774\uc2a4\ub4e4\uc740 \uc774\uc81c \ucc3e\uc544\ubcf4\uba74\uc11c \ud574\uacb0\ucc45\uc744 \ucc3e\uc544\uc57c\uc9c0 \ubb50. \uc5b4\uca0c\ub4e0 Flow\ub294 \uc5ec\uae30\uc11c \ub05d.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">\ucc38\uace0\uc790\ub8cc<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/elizarov.medium.com\/shared-flows-broadcast-channels-899b675e805c\">Shared flows, broadcast channels<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/kt.academy\/article\/cc-sharedflow-stateflow\">Shared flow, State flow &#8211; Kt. Academy<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/developer.android.com\/kotlin\/flow\/stateflow-and-sharedflow\">StateFlow and SharedFlow &#8211; Android guide<\/a><\/li>\n<\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\uc548\ub4dc\ub85c\uc774\ub4dc\uc5d0\uc11c Flow\ub85c \uc77d\uc5b4\uc624\ub294 \ub370\uc774\ud130\ub294 UI\uc5d0 \uc0ac\uc6a9\ub420 \uc2dc, \uc8fc\ub85c viewmodel\uc5d0 \uc800\uc7a5\ud558\ub294 livedata\ud615\ud0dc\ub85c \ubcc0\ud658\ud574\uc11c \uc0ac\uc6a9\ud558\uac8c \ub41c\ub2e4. UI \uc5c5\ub370\uc774\ud2b8\ub294 observable\ud55c \ub370\uc774\ud130\ub97c \ud544\uc694\ub85c \ud558\uae30 \ub54c\ubb38\uc774\ub2e4. Flow\ub294 cold stream\uc774\uae30 \ub54c\ubb38\uc5d0 observable\ud55c \ud615\ud0dc\ub294 \ubd88\uac00\ub2a5\ud558\ub2e4. \uc635\uc800\ubc84 \ud328\ud134\uc740 \ub2e4\ub978\ub9d0\ub85c \ubc1c\ud589-\uad6c\ub3c5(Publisher-Subscriber) \ubaa8\ub378\ub85c \ub9d0\ud558\uae30\ub3c4 \ud558\ub294\ub370, \ubc1c\ud589\ud558\ub294 \ucabd\uc774 \ub370\uc774\ud130\uac00 \ubc14\ub014 \ub54c\ub9c8\ub2e4 \uad6c\ub3c5\uc790\ub4e4\uc5d0\uac8c \ube0c\ub85c\ub4dc \uce90\uc2a4\ud305\uc744 \ud574\uc57c\ud558\uae30 \ub54c\ubb38\uc5d0, hot stream \ud615\ud0dc\ub85c \uad6c\ud604\ub418\uc5b4\uc57c \ud55c\ub2e4. <a href=\"http:\/\/batmask.net\/index.php\/2023\/08\/03\/1986\/\" class=\"btn btn-link continue-link\">\ub354 \uc77d\uae30<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,34],"tags":[186,25,329,38,334,335,336,337,20,326,41,330],"class_list":["post-1986","post","type-post","status-publish","format-standard","hentry","category-android","category-kotlin","tag-android-2","tag-coroutine","tag-flow","tag-kotlin","tag-shared-flow","tag-sharedflow","tag-state-flow","tag-stateflow","tag-android","tag-326","tag-kotlin-kr","tag-330"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1986","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/comments?post=1986"}],"version-history":[{"count":18,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1986\/revisions"}],"predecessor-version":[{"id":3380,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/posts\/1986\/revisions\/3380"}],"wp:attachment":[{"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/media?parent=1986"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/categories?post=1986"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/batmask.net\/index.php\/wp-json\/wp\/v2\/tags?post=1986"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}