ViewModel
- ViewModel이란 Android Jetpack의 구성요소 중 하나.
- MVVM(Model - View - ViewModel) 디자인 패턴으로부터 파생됨.
- AAC ViewModel 이라고 부르기도 한다.
ViewModel의 특징
- 라이프 사이클을 고려하여 UI 관련된 데이터를 저장, 관리하기 위해 설계.
- 화면 전환과 같이 설정이 변경되는 상황에서도 Data를 유지시킨다.
- Activity가 끝날 때까지 사라지지 않고, View의 생명주기와 별개로 흘러간다.
- ViewModel은 Activity 생명주기 외부에 존재하기 때문에 UI 컨텍스트를 ViewModel에 저장한다면 Memory Leak을 발생시키는 원인이 될 수 있다.
ViewModel의 생명주기
일반적으로 onCreate()를 처음 호출할 때 ViewModel을 요청한다.
onCreate()는 화면이 회전할 때 등 여러 번 호출될 수 있다. 이 때 ViewModel은 여전히 메모리 상에 남아있다.
Activity의 finish() 호출 등에 의해 액티비티 생명주기가 종료됨에 따라, LifecycleEventobserver를 통해 ViewModel도 onCleared() 콜백 메서드를 호출하고 종료된다.
ViewModel 구현
// ViewModel Class
public class MyViewModel extends ViewModel {
private MutableLiveData<List<User>> users;
public LiveData<List<User>> getUsers() {
if (users == null) {
users = new MutableLiveData<List<User>>();
loadUsers();
}
return users;
}
private void loadUsers() {
// Do an asynchronous operation to fetch users.
users.add(new User("name", 1);
}
}
ViewModel을 사용하려면 ViewModel 클래스를 상속받아서 사용하며, LiveData에 원하는 데이터를 세팅하여 사용한다.
// MainActivity class
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class);
model.getUsers().observe(this, users -> {
// update UI
sampleText.setText(user);
});
}
}
ViewModel을 생성하기 위해서는 ViewModelProvider 객체가 필요하다.
ViewModelProvider를 이용하여 ViewModel 객체를 생성하고 LiveData 객체를 받아 UI를 업데이트 하는 방식으로 사용한다.
Fragment간의 Data 공유
액티비티 내에서 Fragment간의 데이터, 이벤트 공유는 일반적이다.
이 때, ViewModel을 사용하여 이를 공유하도록 구현한다면, Fragment간의 데이터, 이벤트 공유를 쉽게 처리할 수 있다.
public class SharedViewModel extends ViewModel {
private final MutableLiveData<Item> selected = new MutableLiveData<Item>();
public void select(Item item) {
selected.setValue(item);
}
public LiveData<Item> getSelected() {
return selected;
}
}
public class MasterFragment extends Fragment {
private SharedViewModel model;
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
itemSelector.setOnClickListener(item -> {
model.select(item);
});
}
}
public class DetailFragment extends Fragment {
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SharedViewModel model = new ViewModelProvider(getActivity()).get(SharedViewModel.class);
model.getSelected().observe(getViewLifecycleOwner(), { item ->
// Update the UI.
});
}
}
위의 예제는 SharedViewModel에 Master, Detail Fragment 두 개가 동시에 접근하고 있다.
여기서 getActivity()를 사용해서 ViewModeProvider 객체를 얻기 때문에 두 Fragment에서 사용하는 ViewModel은 동일한 인스턴스가 된다.
따라서, Fragment의 생명주기 동안에 ViewModel을 사용하여 자유롭게 데이터를 공유할 수 있게 된다.
이와 같이 ViewModel을 공유하여 Fragment가 데이터를 공유하는 방법은 다음과 같은 장점을 갖는다.
- Activity가 각 Fragment간 데이터 전달 시 추가적인 작업을 하지 않아도 된다. (Activity가 Fragment 커뮤니케이션에 개입하지 않는다)
- 각 Fragment는 SharedViewModel 외 다른 부분에 의존하지 않아도 된다. 따라서, Fragment 중 하나가 사라지더라도 다른 Fragment는 정상 동작 한다. (Fragment간 의존하지 않는다)
- 각 Fragment는 각각의 생명주기를 가지고 있다. 따라서, 서로의 생명주기에 영향을 주거나 받지 않는다.
즉, Activity와 Fragment들의 의존성이 낮아지면서 유지보수나 확장성 측면에서 높은 효율을 볼 수 있다.
'Android > AAC' 카테고리의 다른 글
[Android] AAC Navigation 사용 실전 압축 정리 (0) | 2022.02.14 |
---|---|
[Android] 데이터 바인딩 어댑터 (Data Binding Adapter) 사용 방법 (0) | 2022.02.07 |
[Android] Room 라이브러리 (0) | 2020.06.22 |
[Android] LiveData 기본 개념 (0) | 2020.06.20 |
[Android] 데이터 바인딩 (Data Binding) 기본 사용 방법 (0) | 2020.06.15 |