SensorManager Recomposition Trouble Shooting

: ) YOUNG·2024년 7월 17일
1

안드로이드

목록 보기
26/30
post-thumbnail
post-custom-banner

SensorManager를 활용해서 걸음 수 정보를 가져올 수 있었으나 전체가 Recomposition이 일어나는 현상이 발생함


트러블 슈팅

  • 걸음수를 측정하는 건 SensorManager를 활용해서 가져올 수 있었으나

SensorManager의 EventListener가 동작할 때 마다 recomposition하여 화면이 전체가 새로 고침되는 현상이 발생


@Composable
fun StepCounterSensorManager(
    walkingRecordViewModel: WalkingRecordViewModel
): Float {
    val context = LocalContext.current
    val sensorManager = remember {
        context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    var stepCount by rememberSaveable { mutableFloatStateOf(0f) }
    val stepCounterSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
    val sensorEventListener = remember {
        object : SensorEventListener {
            override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
                // 정확도 변경 처리
            }

            override fun onSensorChanged(event: SensorEvent) {
                // 걸음 수 업데이트 처리
                stepCount = event.values[0]
            }
        }
    }

    DisposableEffect(Unit) {
        stepCounterSensor?.let {
            sensorManager.registerListener(
                sensorEventListener, it, SensorManager.SENSOR_DELAY_NORMAL
            )
        }

        onDispose {
            // sensorManager.unregisterListener(sensorEventListener)
        }
    }

    // walkingRecordViewModel.setStepCount(stepCount.toInt())
    return stepCount
} // End of rememberStepCounterSensorState()


Composable Screen


StepCounterSensorManager(walkingRecordViewModel) // 걸음수 측정 함수 호출

walkingRecordViewModel.todayStepCount.collectAsState() //  얘가 문제임

WalkScreenContent(navController, walkViewModel) // 전체 화면 호출




원인

SensorManager의 EventListener가 계속 실행이되고
걸음 수를 ViewModel에 저장하였음 그러나 ViewModel에 저장되는 값을 Compose에서 호출해서 사용할 때

전체 화면 Screen에서 collectAsState를 사용하여 UI에 변경 된 값을 수정하려고 했음

문제는 collectAsState가 될 때 전체 UI state가 변경되기 때문이었음



개선

ViewModel에 값을 저장하는 것 까지는 OK 변경할 필요가 없었음

그러나 걸음수를 표시하는 Text상자를 따로 컴포넌트 형식으로 분리해서 해당 컴포넌트만 recomposition이 되도록함으로써 문제를 해결 할 수 있었음


@Composable
fun WalkRecordingBox(
    context: Context,
    moveDist: Double,
    moveStepCount: Int,
    todayStepCount: Int = 0,
    walkingRecordViewModel: WalkingRecordViewModel = hiltViewModel()
) {

 val todayStepCount = walkingRecordViewModel.todayStepCount.collectAsStateWithLifecycle().value

...

Text(text = todayStepCount)
...

}


생각보다 너무 많은 시간을 소비하였는데, Compose의 생명주기와 State에 대해서 더 많은 공부가 필요하다는 것을 알게되었다.

그리고 UI 변경 중 부분만 변경되어야 하는 상황에서는
작은 Componenet 단계로 분리를 하여 State를 관리하는 것이 좋음을 알게되었고
통합으로 관리할 때 는 보다 신중하게 State를 관리해야 한다는 생각을 하게된 좋은 계기가 되었다.

post-custom-banner

0개의 댓글