ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Android] ViewModel의 생성과 Lifecycle 생명주기
    안드로이드 2024. 3. 29. 12:32

    📝 공부한 내용 정리

    ViewModel

    1. ViewModel의 생성

    ViewModel을 사용하려면, 우선 ViewModel 요청을 해야 한다. ViewModelProvider을 사용해서 객체를 요청한다.

     

    1.1) ViewModel의 생성법

     

    - ViewModelProvider 사용

    // 일반적인 방법: ViewModelProvider를 사용하여 뷰모델을 생성 
    viewModel = ViewModelProvider(this).get(SignUpViewModel::class.java)

    this는 액티비티 또는 프래그먼트의 인스턴스이다. SignUpViewModel::class.java는 뷰모델의 클래스를 지정한다. ViewModelProvider는 뷰모델의 인스턴스를 관리하며, 이미 생성된 경우에는 기존 인스턴스를 반환하고, 새로 생성해야 하는 경우 새로운 인스턴스를 생성한다.

     

    - viewModels() 함수 사용

    // KTX(Kotlin Android Extensions)라이브러리의 일부인 viewModels() 함수 사용
    val counterViewModel: CounterViewModel by viewModels()

    lifecycle-viewmodel-ktx에 있는 Lazy를 사용한 방법이다. 위와 동일한 ViewModelProvider를 사용하여 객체를 요청한다.

    viewModels()는 프래그먼트나 액티비티의 범위 내에서 뷰모델을 생성하고 반환한다. by 키워드는 뷰모델을 위임(delegate)하는 역할을 한다. 이 방법은 좀 더 간결하고 편리하며, 프래그먼트나 액티비티의 라이프사이클에 맞춰 자동으로 뷰모델을 생성하고 관리한다.

     

     

    1.2) ViewModelProvider 생성자

    public ViewModelProvider(@NonNull ViewModelStoreOwner owner)
    
    public ViewModelProvider(
        @NonNull ViewModelStoreOwner owner,
        @NonNull ViewModelProvider.Factory factory
    )

     

     

    1.2.1) ViewModelStoreOwner 인터페이스

    ViewModelStoreOwner는 뷰모델을 저장하고 관리하는 데 사용되는 인터페이스이다.ViewModelStoreOwner를 구현한 클래스는 뷰모델 스토어(ViewModelStore)를 가지고 있으며, 이 스토어를 사용하여 뷰모델의 생명주기를 관리한다.

    public interface ViewModelStoreOwner {
        @NonNull
        ViewModelStore getViewModelStore();
    }

    이 인터페이스는 getViewModelStore() 메소드를 포함하고 있다. 이는 ViewModelStore 객체를 반환하는데, 이 객체는 뷰모델의 인스턴스를 저장하고 관리한다.

     

    - ViewModelStoreOwner 인터페이스를 구현하는 클래스
      (ComponentActivity, Fragment를 상속한 클래스 또한 ViewModelStoreOwner 인터페이스의 성격을 갖는다.)

    • ComponentActivity
      • FragmentActivity
        • AppCompatActivity
    • Fragment
      • DialogFragment
        • AppCompatDialogFragment

     

    1.2.2) ViewModelProvider.Factory 인터페이스

    ViewModelProvider.Factory는 뷰모델의 인스턴스를 생성하는 데 사용되는 인터페이스이다. 이를 통해 사용자가 뷰모델의 생성 과정을 제어하고 사용자 지정 로직을 구현할 수 있다.

    일반적으로 뷰모델을 생성할 때, 빈 생성자가 필요하며, 이는 많은 경우로 문제가 될 수 있다. 예를 들어 뷰모델이 생성될 때 필요한 데이터나 의존성이 있는 경우 빈 생성자만으로는 충분하지 않다. 이런 경우에 ViewModelProvider.Factory를 사용하여 사용자 정의한 팩토리를 제공하고, 이 팩토리를 통해 뷰모델을 생성할 수 있다.

    public interface Factory {
        @NonNull
        <T extends ViewModel> T create(@NonNull Class<T> modelClass);
    }

     

    create() 메소드는 제네릭 타입의 뷰모델을 생성하고 반환한다. 이 메서드는 뷰모델 클래스(Class<T> modelClass)를 인자로 받아 해당 클래스의 인스턴스를 생성한다. 이를 통해 사용자는 필요한 데이터나 의존성을 뷰모델에 제공할 수 있다. ViewModelProvider.Factory를 통해 뷰모델의 생성 프로세스를 커스터마이징하고 필요한 의존성을 제공하여 더 유연하고 안정적인 앱을 개발할 수 있다.

     

    1.3) ViewModel 생성 과정

    1. ViewModelProvider 객체 생성
    2. ViewModelProvider, get()을 통해 ViewModel 요청
    3. ViewModelStore에 없을 경우, ViewModelProvider.Factory을 통해서 객체 생성 후 반환
    4. ViewModelStore에 인스턴스화한 ViewModel을 저장

     

    2. ViewModel의 Lifecycle

    2.1) ViewModelStore

    ViewModel 객체를 HashMap 구조로 저장하는 클래스이다. 일반적으로 ViewModelStore ViewModelProvider를 통해 뷰모델을 생성할 때 사용된다. ViewModelProvider는 연결된 ViewModelStoreOwner에서 해당 ViewModelStore를 가져와 사용하여 뷰모델을 생성하고 관리한다. 뷰모델은 해당 ViewModelStore에 저장되어 있으며, 해당 ViewModelStore가 파괴될 때까지 메모리에 남아있다.

    public class ViewModelStore {
        private final Map<String, ViewModel> mMap = new HashMap<>();
    
    }

    ViewModelStore는 액티비티나 프래그먼트의 생명주기에 연결되어 있다. 따라서 액티비티나 프래그먼트가 파괴되면 해당 ViewModelStore도 함께 파괴된다. 이는 뷰모델의 생명주기와 관련이 있다.

    ViewModelStore는 ViewModel의 소유자(Owner)가 인스턴스 형태로 가지고 있으므로  소유자의 생명주기 종료시, ViewModelStore clear()를 호출(이때,ViewModelStore 내부에서 각 뷰모델의 onCleared() 메서드가 호출됨)하여 ViewModel이 종료되도록 한다.

     

    2.2) ViewModel 소멸

    • Activity: finish 될 때
    • Fragment: detach 될 때

    https://www.androhub.com/android-fragments/


     

    📌 참고&출처 : https://pluu.github.io/blog/android/2020/05/04/viewmodel-b-to-d/ 

Designed by Tistory.