YAPP-Github / 21st-Android-Team-1-Android

Apache License 2.0
8 stars 0 forks source link

[Question] Flow 데이터 수집 관련 #88

Open hanchang97 opened 1 year ago

hanchang97 commented 1 year ago

관련된 기능

Flow 개념

문제

Flow를 사용하던 도중 질문이 생겼습니다!

class MainViewModel : ViewModel() {
    private val _testStateFlow = MutableStateFlow(1)
    val testStateFlow = _testStateFlow.asStateFlow()

    fun flowTest() {
        viewModelScope.launch {
            _testStateFlow.value = 2
            //delay(1)
            _testStateFlow.value = 3

            _testStateFlow.value = 4
        }
    }
}
class MainActivity : AppCompatActivity() {

    private val mainViewModel: MainViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        init()
        observeData()
    }

    private fun init() {
        mainViewModel.flowTest()
    }

    private fun observeData() {
        lifecycleScope.launch {
            repeatOnLifecycle(Lifecycle.State.STARTED) {
                mainViewModel.testStateFlow.collect {
                    Log.e("AppTest", "value : ${it}")
                }
            }
        }
    }
}

참고 사항

ows3090 commented 1 year ago

@hanchang97 창희님 observeData 호출먼저하고 init 해보시겠어요? init 먼저 호출하셔서 2,3,4 다 호출되고 stateflow에 저장된 4만 수집하는 것 같아요

hanchang97 commented 1 year ago

@ows3090 아까 그렇게도 해봤는데 똑같이 마지막 값만 수집합니다..!

ashwon12 commented 1 year ago

StateFlow 는 Flow 와는 다르게 가장 마지막 값의 값만 collect 되기 때문인 것 아닌가요?! testStateFlow 의 타입이 Flow 였다면 2,3,4 값이 모두 수집이 될 텐데 StateFlow 는 단일값을 가지기 때문에 맨 마지막 값만 수집된다고 생각됩니당

ows3090 commented 1 year ago

@hanchang97 창희님 그럼 init을 onResume에 호출해보시겠어요?

hanchang97 commented 1 year ago

@ows3090 초기값으로 설정한 1 그리고 마지막 4 이렇게만 나옵니다!

ows3090 commented 1 year ago

StateFlow 는 Flow 와는 다르게 가장 마지막 값의 값만 collect 되기 때문인 것 아닌가요?! testStateFlow 의 타입이 Flow 였다면 2,3,4 값이 모두 수집이 될 텐데 StateFlow 는 단일값을 가지기 때문에 맨 마지막 값만 수집된다고 생각됩니당

StateFlow도 Flow를 상속받기 때문에 동일한 역할은 할거에요 다만 마지막 값을 가지고 있습니다. 즉 hot stream이냐 cold. stream이냐 차이만 있을거에요! @ashwon12

ows3090 commented 1 year ago

@ows3090 초기값으로 설정한 1 그리고 마지막 4 이렇게만 나옵니다!

저도 한번 테스트 해볼게요!

hanchang97 commented 1 year ago

StateFlow 는 Flow 와는 다르게 가장 마지막 값의 값만 collect 되기 때문인 것 아닌가요?! testStateFlow 의 타입이 Flow 였다면 2,3,4 값이 모두 수집이 될 텐데 StateFlow 는 단일값을 가지기 때문에 맨 마지막 값만 수집된다고 생각됩니당

일반 flow 빌더에서 2, 3, 4 차례대로 emit 을 하면 모두 수집되는건 맞을 겁니다 다만 Flow는 state holder의 역할이 불가능하여 지금 상황에서는 어떻게 해결해야 할지 질문드렸습니다!

ows3090 commented 1 year ago

@hanchang97 창희님

listOf(1,2,3).asFlow().collect{
            _testStateFlow.value = it
        }

이런 방식도 있을것 같아요!

hanchang97 commented 1 year ago
fun flowTest() {
        viewModelScope.launch(Dispatchers.Main) {
            _testStateFlow.value = 2
            //delay(1)

            _testStateFlow.value = 3

            _testStateFlow.value = 4
        }
    }

@ows3090 @ashwon12 명시적으로 디스패처 메인을 선언하면 모두 수집이 되는데 왜일까요..ㅎㅎ

ows3090 commented 1 year ago

@hanchang97 창희님 메인스레드는 비동기가 아니여서 그러지 않을까요?

hanchang97 commented 1 year ago

https://jisungbin.medium.com/dispatchers-main-immediate-%EC%9D%98-%EB%8C%80%ED%95%9C-%EC%9D%B4%ED%95%B4-9f073be21e5a @ows3090 @ashwon12

ows3090 commented 1 year ago

@hanchang97 창희님 위 블로그 보니 조금 헷갈리는데 viewModelScope의 기본 Dispatcher가 Dispatcher.Main.immediate 라는거죠? 동기적일 때가 모두 수집되어야 하는거 아닌가요?