[Android] ViewModel(), by viewmodels(), AndroidViewModel(application) 이 뭔 차이인지 알아보기

도톨이·2024년 9월 27일

Kotlin

목록 보기
4/10

카테캠 프로젝트를 진행하다가 뷰모델이 많은데 무엇을 사용해야할까? 라는 의문에서 한 번 정리해보기로 하였다.

1. by viewModels()

by viewModels() 은 프래그먼트나 액티비티에서 ViewModel의 인스턴스를 간단히 가져올 때 사용한다.
화면 전환같은 걸 하게 되면 Activity, Fragment 가 파괴/재생성 되는데 by viewModels() 를 통해 뷰모델의 인스턴스를 가져오면 ViewModelStore 에 저장되기 때문에 재생성되더라도 ViewModelStore 가 이전 상태를 유지하기 떄문에 ViewModel 을 ViewModelStore에서 가져와서 데이터를 보존할 수 있다.

  • by viewModels() 를 사용해 얻은 ViewModel 은 화면 회전으로 Activity, Fragment 가 파괴되고 재생성되더라도 유지됨
  • ViewModel 은 Fragment 와 Activity 와는 독립적

ex) 예시

class MyFragment : Fragment() {
    private val viewModel: MyViewModel by viewModels()

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // viewModel은 화면 회전 후에도 동일한 인스턴스를 유지함
        return inflater.inflate(R.layout.fragment_my, container, false)
    }
}

2. ViewModel()

1이랑은 약간 다른 관점? 같은 것이다. 1은 액티비티나 프래그먼트에서 뷰모델을 가져올 때 쓰는 방법이었다면 이는 ViewModel 클래스를 생성할 때 쓰인다.

ViewModel의 기본 구현체이다.

예시)

class MyViewModel : ViewModel() {
    // ViewModel logic here
}

즉, ViewModel() 로 뷰모델 클래스를 구현한 후 이 뷰모델을 Activity 나 Fragment 에서 사용할 때 by viewModels() 를 이용해서 가져올 수 있다

요약
1. ViewModel()로 ViewModel 클래스를 먼저 구현
2. Activity나 Fragment에서 by viewModels()를 사용해 해당 ViewModel의 인스턴스를 가져와 사용

3. AndroidViewModel(application)

AndroidViewModel 은 ViewModel 의 서브클래스로 안드로이드의 Application 컨텍스트에 접근이 필요할 경우에 사용한다.
일반적인 ViewModel 은 Activity 나 Fragment 의 수명주기와 연동되어 데이터를 관리할 수 있지만 시스템 리소스(데이터베이스, 파일, SharedPref 등) 에 접근할 때는 Context 를 필요로 하기 때문에 이때 AndroidViewModel을 사용하면 Application 컨텍스트를 활용할 수 있다.

가져와서 쓸 때에는 아까 2번에서 했던 것처럼 by viewModels() 로 가져와 쓸 수 있다.

예시)

class MyAndroidViewModel(application: Application) : AndroidViewModel(application) {
    private val context = application.applicationContext
    
    // 예: 데이터베이스나 SharedPreferences를 활용하는 로직
    fun loadPreferences(): String {
        val sharedPreferences = context.getSharedPreferences("my_prefs", Context.MODE_PRIVATE)
        return sharedPreferences.getString("key", "default") ?: "default"
    }
}
class MyActivity : AppCompatActivity() {
    private val myViewModel: MyAndroidViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // Use myViewModel to access data or interact with the application context
        val data = myViewModel.loadPreferences()
    }
}

Application 컨텍스트는 안드로이드에서 전역적으로 사용 가능한 컨텍스트로 액티비티 컨텍스트와는 다르게 앱의 수명 주기 동안 계속 존재하는 컨텍스트이다. 따라서 데이터베이스, SharedPref, 파일 시스템 접근, 싱글톤 객체, 글로벌 설정을 다룰 때만 사용한다.

profile
Kotlin, Flutter, AI | Computer Science

0개의 댓글