ViewModel 개요 (뷰)
ViewModel 클래스는 비즈니스 로직 또는 화면 수준 상태 홀더입니다. UI에 상태를 노출하고 관련 비즈니스 로직을 캡슐화합니다.
주요 이점은 상태를 캐시하여 구성 변경에도 이를 유지한다는 것입니다. 즉, Activity 간에 이동하거나 구성 변경(예: 화면 회전 시)을 따를 때 UI가 데이터를 다시 가져올 필요가 없습니다.
ViewModel의 이점
ViewModel의 대안은 UI에 표시되는 데이터를 보유하는 일반 클래스입니다. 이는 활동이나 탐색 대상 간에 이동할 때 문제가 될 수 있습니다. 이렇게 하면 저장된 인스턴스 상태 메커니즘을 사용하여 데이터를 저장하지 않을 경우 해당 데이터가 소멸됩니다. ViewModel은 데이터 지속성을 위한 편리한 API를 제공하여 이 문제를 해결합니다.
ViewModel 클래스의 주요 이점은 기본적으로 두 가지입니다.
- UI 상태를 유지할 수 있습니다.
- 비즈니스 로직에 대한 액세스 권한을 제공합니다.
범위
ViewModel을 인스턴스화할 때는 ViewModelStoreOwner 인터페이스를 구현하는 객체를 전달합니다. 이는 탐색 대상, 탐색 그래프, 활동, 프래그먼트 또는 인터페이스를 구현하는 다른 유형일 수 있습니다. 그러면 ViewModel의 범위가 ViewModelStoreOwner의 Lifecycle로 지정됩니다. 이는 ViewModelStoreOwner가 영구적으로 사라질 때까지 메모리에 남아 있습니다.
클래스 범위는 ViewModelStoreOwner 인터페이스의 직접 또는 간접 서브클래스입니다. 직접 서브클래스는 ComponentActivity, Fragment, NavBackStackEntry입니다.
간접 서브클래스의 전체 목록은 ViewModelStoreOwner 참조를 확인하세요.
ViewModel 구현
다음은 사용자가 주사위를 굴릴 수 있는 화면을 나타내는 ViewModel의 구현 예입니다.
Kotlin
data class DiceUiState(
val firstDieValue: Int? = null,
val secondDieValue: Int? = null,
val numberOfRolls: Int = 0,
)
class DiceRollViewModel : ViewModel() {
// Expose screen UI state
private val _uiState = MutableStateFlow(DiceUiState())
val uiState: StateFlow<DiceUiState> = _uiState.asStateFlow()
// Handle business logic
fun rollDice() {
_uiState.update { currentState ->
currentState.copy(
firstDieValue = Random.nextInt(from = 1, until = 7),
secondDieValue = Random.nextInt(from = 1, until = 7),
numberOfRolls = currentState.numberOfRolls + 1,
)
}
}
}
자바
public class DiceUiState {
private final Integer firstDieValue;
private final Integer secondDieValue;
private final int numberOfRolls;
// ...
}
public class DiceRollViewModel extends ViewModel {
private final MutableLiveData<DiceUiState> uiState =
new MutableLiveData(new DiceUiState(null, null, 0));
public LiveData<DiceUiState> getUiState() {
return uiState;
}
public void rollDice() {
Random random = new Random();
uiState.setValue(
new DiceUiState(
random.nextInt(7) + 1,
random.nextInt(7) + 1,
uiState.getValue().getNumberOfRolls() + 1
)
);
}
}
그 후에 다음과 같이 활동에서 ViewModel에 액세스할 수 있습니다.
Kotlin
import androidx.activity.viewModels
class DiceRollActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same DiceRollViewModel instance created by the first activity.
// Use the 'by viewModels()' Kotlin property delegate
// from the activity-ktx artifact
val viewModel: DiceRollViewModel by viewModels()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect {
// Update UI elements
}
}
}
}
}
자바
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Create a ViewModel the first time the system calls an activity's onCreate() method.
// Re-created activities receive the same MyViewModel instance created by the first activity.
DiceRollViewModel model = new ViewModelProvider(this).get(DiceRollViewModel.class);
model.getUiState().observe(this, uiState -> {
// update UI
});
}
}
추천 서비스
- 참고: JavaScript가 사용 중지되어 있으면 링크 텍스트가 표시됩니다.
- 수명 주기 인식 구성요소로 Kotlin 코루틴 사용
- UI 상태 저장
- 페이징 데이터 로드 및 표시