์ด ๊ธ์ ์ฝ๊ธฐ ์ ์ Flow๋? ๊ธ์ ์ฝ์ง ์์ผ์ จ๋ค๋ฉด ์ฝ๋ ๊ฒ์ ์ถ์ฒ๋๋ฆฝ๋๋ค.
Flow๋ ํน์ ์์ ์ ๋ฐ์ดํฐ๋ฅผ ์๊ธฐ ์ด๋ ค์ ๊ณ , ์ํ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค UI์์ ๋งค๋ฒ ๊ตฌ๋
์ ํ๊ธฐ์ ๊ฐ๋ฐ์ ์ด๋ ค์์ด ์์ต๋๋ค.
์ด๋ฅผ ๋ณด์ํ๊ธฐ ์ํด StateFlow๊ฐ ๋ฑ์ฅํ์ต๋๋ค.
StateFlow๋ ํญ์ ํ์ฌ ๊ฐ์ ๊ฐ์ง๋ฉฐ, ๊ตฌ๋
ํ๊ณ ์๋ ๋ชจ๋ ๊ตฌ๋
์์๊ฒ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์ฆ์ ์๋ ค์ฃผ๊ธฐ์ ๊ตฌ๋
๋ง ํ๊ณ ์์ผ๋ฉด ๋ฉ๋๋ค.
์ด๋ฅผ ํตํด ์ํ๋ ์์ ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ ์์ต๋๋ค.
StateFlow๋ Hot Stream์
๋๋ค.
Hot Stream ์ด๋ ๋ฆฌ์กํฐ๋ธ ํ๋ก๊ทธ๋๋ฐ(๋ฐ์ํ ํ๋ก๊ทธ๋๋ฐ)์์ ์ฌ์ฉ๋๋ ๊ฐ๋
์ผ๋ก, ๋ฐ์ดํฐ๊ฐ ๋ฐ๋๋ฉด ๋ฐ๋ ๋ด์ฉ์ ๋ฐ๋ก๋ฐ๋ก ์
๋ฐ์ดํธํ ์ ์๋๋ก ํ๋ ๋ฐฉ์์
๋๋ค.
์ฆ, ์ค์๊ฐ ๋ฐ์ดํฐ์ฒ๋ฆฌ์ ์ ํฉํ ํน์ฑ์ ๊ฐ์ง Stream์
๋๋ค.
๐โ๐จ Flow์ ๊ดํ ๊ธ์์๋ ์ ์๊ธฐ๋ก ์๋ฅผ ๋ค์๋๋ฐ ์ด๋ฒ์๋ ์ ์๊ธฐ๋ก ์๋ฅผ ๋ค์ด๋ณด๊ฒ ์ต๋๋ค.
๋ฌผํฑํฌ = ์์ฐ์ / ์ ์๊ธฐ์ ๋ฌผ ์ํ ๋ณ๊ฒฝ ๊ธฐ๋ฅ = ์ค๊ฐ์ / ์ฌ๋ = ์๋น์ / ๋ฌผ = data
์ด๋ฒ์ ๋ฌผํฑํฌ์ ๋ฌผ์ด ์ด๋ฏธ ์์ฐ๋์ด ์์ต๋๋ค.
์ ์๊ธฐ๋ก ๋ฌผ์ ์จ์๋ก ํ ์ง, ๋์๋ก ํ ์ง, ์ผ์์ผ๋ก ํ ์ง ๋ณ๊ฒฝ์ด ๊ฐ๋ฅํฉ๋๋ค.
์ฌ๋์ด ๋ฌผ์ ์๋น(collect)ํ๋ฉด ์ ์๊ธฐ์์ ๋ฌผ์ด ๋์ ๋ฌผ์ ๋ง์ค ์ ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์ด๋ฒ์ ํน๋ณํ ๊ธฐ๋ฅ์ด ์ถ๊ฐ๋์๋ค๊ณ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
StateFlow๋ Hot Stream์ผ๋ก ๋ฐ์ดํฐ๊ฐ ์์ฑ๋์ด ์๊ณ ์ํ๊ฐ ์ ์ง๋์ด ์์ต๋๋ค.
๊ทธ๋์ ์ ์๊ธฐ์ ๋ฌผ์ ์๋น(collect)ํ๊ธฐ ์ํด ๋ฒํผ์ ๋๋ ๋๋ ๋ฌผ์ด ๋ฉ์ถ์ง ์๊ณ ๊ณ์ ๋์ค๋ ๊ฒ๋๋ค.
(์ด ๋ฌธ์ ์ ํด๊ฒฐ๋ฐฉ๋ฒ์ ์๋์์ ๋ค๋ค ๋ณด๊ฒ ์ต๋๋ค.)
๊ทธ๋ฆฌ๊ณ ์ ์๊ธฐ์์ ๋์จ ๋ฌผ์ ์ ์๊ธฐ์ ๋ฃ์ผ๋ฉด ์ฌ์ฌ์ฉํ ์ ์๋ค๊ณ ์๊ฐํด ๋ณด๊ฒ ์ต๋๋ค.
๊ทธ๋ฌ๋ฉด ๋ฐ๋ผ๋์ ๋ฌผ(ํน์ ์์ ์ data)์ ๊ฐ์๊ธฐ ์ผ์์ผ๋ก ๋จน๊ณ ์ถ๋ค๋ฉด ๋ฌผ์ ์ ์๊ธฐ์ ๋ฃ์ผ๋ฉด ์ผ์์ผ๋ก ๋ณํ์ํฌ ์ ์์ต๋๋ค.
StateFlow์ LiveData๋ ๋น์ทํ ์ ์ด ๋ง์ต๋๋ค.
๋ชจ๋ ๋ฐ์ดํฐ ํ๋ ํด๋์ค๋ก ์ํ๋ฅผ ๊ด์ฐฐํ์ฌ ์ํ ๊ด๋ฆฌํ๋ ๋ฐ ์ฌ์ฉ ๋ฉ๋๋ค.
์ํ๋ฅผ ๊ด์ฐฐํ์ฌ ๊ด๋ฆฌํ๊ธฐ ๋๋ฌธ์ ์ต์ ์ ์ํ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค.
ํ์ง๋ง LiveData๋ ์๋ช
์ฃผ๊ธฐ๋ฅผ ์ธ์ํ๊ณ ์์ด์ ์๋ช
์ฃผ๊ธฐ๊ฐ ํ๊ดด๋ ๋ ๊ฐ์ด ํ๊ดด๋์ง๋ง StateFlow๋ ๊ทธ๋ ์ง ์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ ์๋๋ก์ด๋ ๊ณต์ ๋ฌธ์์์๋ StateFlow๋ฅผ ๊ถ์ฅํ๊ณ ์๋๋ฐ ์ด์ ๋ฅผ ์์๋ณด๊ฒ ์ต๋๋ค.
1. ์ค๋ ๋ ๋ฌธ์
LiveData๋ ๋ฉ์ธ ์ค๋ ๋์์๋ง ๊ฐ์ ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
์ด ๋ป์ Livedata๋ Main ์ค๋ ๋๋ฅผ ๋ฒ์ด๋ Input/Output ์ค๋ ๋ ์ํ ์ฆ ์
๋ ฅ์ด ์ผ์ด๋ ๋ ์ํ๋ฅผ ์
๋ฐ์ดํธํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
2. ๋ฐฑ ํ๋ ์
(Back Pressure) ๋ฌธ์
LiveData๋ ๋ฐฑ ํ๋ ์
๋ฌธ์ ๋ฅผ ๋ค๋ฃจ์ง ์์ต๋๋ค.
๋ฐฑ ํ๋ ์
๋ ๋ฐ์ดํฐ๋ฅผ ์์ฐํ๋ ์๋๊ฐ ์๋นํ๋ ์๋๋ณด๋ค ๋น ๋ฅผ ๋๋ฅผ ์๊ธฐํ๋๋ฐ ์์ ์ ํ ์์๋ก ์ค๋ช
ํ์๋ฉด ๋ฌผํฑํฌ๊ฐ ๋ฌผ์ ์์ฐํ๋๋ฐ ๋ง์ฝ ๋ฌผํฑํฌ ์ฉ๋์ด ์ ํด์ ธ ์๋ค๊ณ ํ ๋, ๋ฌผ์ ๊ณ์ ์์ฐํ๋๋ฐ ๋ฌผ ๋ง์๋ ์ฌ๋์ด ์์ผ๋ฉด ๋ฌผํฑํฌ๊ฐ ํฐ์ ธ ๋ฒ๋ฆฝ๋๋ค.
ํ์ง๋ง StateFlow๋ ๋ฐฑ ํ๋ ์
๋ฌธ์ ๋ฅผ ์๋์ผ๋ก ๊ด๋ฆฌํฉ๋๋ค.
3. ์๋ช
์ฃผ๊ธฐ ๋ณด์
StateFlow๋ ์๋ช
์ฃผ๊ธฐ๋ฅผ ์ธ์ํ์ง ๋ชปํ๋ค๊ณ ํ์ง๋ง lifecycleScope๋ฅผ ํตํด ๋ณด์ํ ์ ์์ต๋๋ค.
์์์์ ๋ฌผ์ด ๊ณ์ ํ๋ฅด๋ ๊ฑธ ๋ฐฉ์งํ๊ธฐ ์ํ ๋ฐฉ๋ฒ๊ณผ ์ ์๊ธฐ๋ก ๋ฐ์ ๋ฌผ์ ์ด๋ป๊ฒ ๋ณํ ์ํฌ ์ ์๋ ๋ฐฉ๋ฒ๋ ๊ฐ์ด ์์ ๋ณด๊ฒ ์ต๋๋ค.
// ViewModel
/** LiveData ํํ **/
private var mutableLiveData = MutableLiveData<Int>()
val liveData : LiveData<Int>
get() = mutableLiveData
/** StateFlow ํํ **/
val mutableStateFlow = MutableStateFlow(0)
fun setData(value : Int)
{
mutableStateFlow.value = value
}
// Activity
/** ๊ฒฐ๊ณผ๊ฐ **/
resultBtn.setOnClickListener {
viewModel.setData(editValue.text.toString().toInt())
lifecycleScope.launch {
viewModel.mutableStateFlow.collect {
resultText.text = it.toString()
}
}
}
repeatOnLifecyclerepeatOnLifecycle์ ์ฌ์ฉํ๋ฉด ๋ฌผ์ด ๊ณ์ ํ๋ฅด๋ ๊ฒ์ ๋ฐฉ์งํ ์ ์์ต๋๋ค.repeatOnLifecycle(Lifecycle.State.STARTED) : ์๋ช
์ฃผ๊ธฐ๊ฐ ์์ ๋ ๋ ๋ฐ์ดํฐ๋ฅผ ๊ด์ฐฐํ๊ณ ์๋ช
์ฃผ๊ธฐ๊ฐ ํ๊ดด๋ ๋ ์๋น์๋ ๊ตฌ๋
์ ํ์ง ์๋ ์ํ๊ฐ ๋ฉ๋๋ค. // Activity
/** ๊ฒฐ๊ณผ๊ฐ **/
resultBtn.setOnClickListener {
viewModel.setData(editValue.text.toString().toInt())
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.mutableStateFlow.collect {
resultText.text = it.toString()
}
}
}
}
map, filter, reduce, transform ๋ค์ํ ์ฐ์ฐ์ ์ฌ์ฉ์ด ๊ฐ๋ฅํฉ๋๋ค. // viewModel
val transformationStateFlow = mutableStateFlow.asStateFlow().map { it * it }
// Activity
/** ๋ณํ๋ ๊ฒฐ๊ณผ ๊ฐ **/
transformationBtn.setOnClickListener {
viewModel.setData(editValue.text.toString().toInt())
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.transformationStateFlow.collect {
resultText.text = it.toString()
}
}
}
}
์ด๋ฒ ์๊ฐ์ StateFlow์ ๋ํด ์์๋ณด์์ต๋๋ค.
LiveData๋ณด๋ค StateFlow๋ฅผ ํ์ฉํ๋ฉด ๋ ์ข์ ๊ฒ ๊ฐ์ต๋๋ค.