Compose 재구성

유시현·2025년 12월 10일

Android

목록 보기
43/55
fun HomeScreen(engine: AudioEngine, onGoSetting: () -> Unit){
    val spl by engine.spl.collectAsState()
    val spectrum by engine.spectrum.collectAsState()
    ...
    
    
    SoundLevelScreen(
                        splValue = spl,
                        splStereo = stereoDbState,
                        spectrum = spectrum,
                        stereoSpectrum = stereoSpectrum
                    )
                    
 }

이렇게 있을때 spl 이 변경되면 SoundLevelScreen 부분만 다시 재구성된다.

@Composable
fun SoundLevelScreen(
    splValue: Double,
    splStereo: Pair<Double, Double>,
    spectrum: FloatArray,
    stereoSpectrum: Pair<FloatArray, FloatArray>
) {

    println("1초 마다 호출")
	...

}

즉 이렇게 1초마다 호출이 된다.

          val splApprox = monoCalculateDb(n, buf)


                            val smoothed = if (ema == null) {
                                ema = splApprox
                                splApprox
                            } else {
                                val v = alpha * splApprox + (1.0 - alpha) * ema!!
                                ema = v; v
                            }
                            _spl.value = splApprox
                            // 스펙트럼만 따로
                            println("호출 _spl 계산끝")
                        	//delay(10)
                            val spec = monoCalculateEqualizer(n, buf, real, imag, spectrumCtx)
                            _spectrum.value = spec
                            println("호출 _spectrum 계산끝")

이게 1초마다 호출되니까 println("호출 _spl 계산끝") 끝나고 SoundLevelScreen 가 재구성되고, println("호출 _spectrum 계산끝") 끝나고 SoundLevelScreen 가 재구성되니 총 1초에 2번 println("1초 마다 호출") 이게 호출되는 것이 아닐까?

-> 아니다. 실제 해보면 1초에 한번씩 println("1초 마다 호출") 가 호출된다.

왜그러냐면 Compose가 “재구성 요청을 합쳐서(coalesce)” 처리하기 때문이다.

내부적은로는 _spl.value = splApprox 되면

Compose: “아 이 Composable(scope) 다시 그려야겠네” 하고 recomposition을 예약만 해 둔다.

recompose()가 시작되기 전에
_spectrum.value = ... 도 바로 실행됨

engine.spectrum.collectAsState() 안 state도 변경됨

Compose: “어? 같은 scope 또 변경됐네. 이미 재구성 예약되어 있으니까 또 스케줄 잡을 필요는 없겠다.”
두 번째 변경은 이미 잡혀 있는 그 한 번의 재구성에 같이 포함

실제로 delay(10) 을 추가하면 println("1초 마다 호출") 가 2번 호출된다.

profile
안드로이드 ,ios 공부하고 있습니다

0개의 댓글