The SoundViewModel is a ViewModel class, and val listSoundRecordState may be used by some modules in the App.
In Code A, I invoke fun collectListSoundRecord() when I need to use the data listSoundRecordState. But fun collectListSoundRecord() may be launched again and again because of Jetpack Compose recomposition, I don't know if it will cost many system resources?
In Code B, I launch  private fun collectListSoundRecord() in init {  }, collectListSoundRecord() will be launched only one time, but it will persist in memory until the App code closed even if I needn't to use the data listSoundRecordState, will the way cost many system resources?
Code A
@HiltViewModel
class SoundViewModel @Inject constructor(
  ...
): ViewModel() {
    private val _listSoundRecordState = MutableStateFlow<Result<List<MRecord>>>(Result.Loading)
    val listSoundRecordState = _listSoundRecordState.asStateFlow()
    init { }
     //It may be launched again and again
    fun collectListSoundRecord(){
        viewModelScope.launch {
            listRecord().collect {
                result -> _listSoundRecordState.value =result
            }
        }
    }
    private fun listRecord(): Flow<Result<List<MRecord>>> {
        return  aSoundMeter.listRecord()
    }
}
Code B
@HiltViewModel
class SoundViewModel @Inject constructor(
  ...
): ViewModel() {
    private val _listSoundRecordState = MutableStateFlow<Result<List<MRecord>>>(Result.Loading)
    val listSoundRecordState = _listSoundRecordState.asStateFlow()
    init { collectListSoundRecord() }
    private fun collectListSoundRecord(){
        viewModelScope.launch {
            listRecord().collect {
                result -> _listSoundRecordState.value =result
            }
        }
    }
    private fun listRecord(): Flow<Result<List<MRecord>>> {
        return  aSoundMeter.listRecord()
    }
}
                You would probably benefit from collecting the original flow (from listRecord()) only when there is a subscriber to your intermediate flow (the one you keep in your SoundViewModel) and cache the results.
A subscriber, in your case, would be a Composable function that collects the values (and may recompose often).
You can achieve this using the non-suspending variant of stateIn(), since you have a default value.
@HiltViewModel
class SoundViewModel @Inject constructor(
    ...
): ViewModel() {
    val listSoundRecordState = listRecord().stateIn(viewModelScope, SharingStarted.WhileSubscribed(), Result.Loading)
    private fun listRecord(): Flow<Result<List<MRecord>>> {
        return  aSoundMeter.listRecord()
    }
}
In order to use the StateFlow from the UI layer (a @Composable function), you will have to transform it into a State, like so:
val viewModel: SoundViewModel = viewModel()
val listSoundRecord = viewModel.listSoundRecordState.collectAsState()
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With