본문으로 바로가기

Hilt 로 Viewmodel 사용하기

category Studies/Android 2022. 4. 10. 00:37

Hilt 를 사용하지 않는 경우, 안드로이드에서 Viewmodel은 Viewmodel Factory라는 일종의 모듈 역할을 하는 클래스에서 뷰모델들의 수명주기를 관리하여 주어야 한다.

ViewModel에 constructor 를 만들려면 ViewModelFactory를 통해 생성한다. 

클래스 코드는 다음과 같다.

 

ViewModelFactroy.kt

class ViewModelFactory(private val param: Context, private val param2: String) : ViewModelProvider.Factory {

    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return if (modelClass.isAssignableFrom(PokemonRankViewModel::class.java)) {
            PokemonRankViewModel(param,param2) as T
        }else if(modelClass.isAssignableFrom(PokemonInfoViewModel::class.java)) {
            PokemonInfoViewModel(param, param2) as T
        }else if(modelClass.isAssignableFrom(PokemonSearchViewModel::class.java)){
            PokemonSearchViewModel(param,param2) as T
        }else if(modelClass.isAssignableFrom(PokemonReviewsViewModel::class.java)) {
            PokemonReviewsViewModel(param, param2) as T
        }
        else {
            throw IllegalArgumentException()
        }
    }
}

Fragment.kt

class MyFragment : Fragment() {

    lateinit var viewmodel:PokemonRankViewModel
    
        override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewmodel = ViewModelProvider(this,ViewModelFactory(requireActivity(),"AttackPokemonRanking"))
            .get(PokemonRankViewModel::class.java)
    }
    
    //
}

 

그런데 Hilt 를 사용하게 되면 Viewmodel 사용법이 위와 좀 달라진다. 

Hilt란 생명 주기를 자동으로 알맞게 관리하도록 하여주는 편리한 종속성 관련 라이브러리인데, Hilt는 Viewmodel의 생명주기 또한 관리하기 때문이다.

 

ViewModel.kt

@HiltViewModel
class PokemonRankViewModel @Inject constructor(
    application: Application):BaseViewModel(application){

 //
}
@HiltViewModel
open class BaseViewModel @Inject constructor(application: Application) : AndroidViewModel(application) {
    protected val context
        get() = getApplication<Application>()
}

Fragment.kt

@AndroidEntryPoint
class AttackPokemonFragment : Fragment() {

    private val viewmodel:PokemonRankViewModel by viewModels()
    //
 }

특이하게 BaseViewModel 을 만들어 context 변수를 만든 후 ViewModel에서 상속받은 것을 알 수 있는데, 

이는 ViewModel에서 Context를 사용하고 싶을 경우다.  

유용한 경우이기 때문에 가져왔다.

 

위의 경우처럼 Hilt 를 사용한다면 ViewModelFactroy 라는 것이 필요 없다. 

ViewModelFactory 라는 것을 사용한다면 어쩔 수 없이 보일러플레이트 코드가 발생하기 마련인데, Hilt는 생명주기를 자동으로 관리하여 주기 때문에 그런 번거로운 코드를 작성할 필요가 없다.

 

위의 측면에서 Hilt를 왜 사용해야 하는지 이유가 나온다. 

 

1. 번거로운 과정을 줄여줌으로써 자연스레 보일러 플레이트 코드를 제거해 준다.

2. 어노테이션을 주입하는 것만으로 생명주기를 자동으로 관리해주기 때문에, 개발자는 성가시게 클래스간의 생명주기에 관해 일일이 신경쓰며 다른 모든 코드를 작성할 필요가 없다.

3. 어노테이션을 기입함으로써 개발자는 Hilt가 어떤 식으로 생명주기를 관리하는지 알고만 있다면 이 클래스가 어느 시점에 들어가고 나오는지 어노테이션을 보는 것 만으로도 단번에 알 수 있다. 

 

 

참조

https://dagger.dev/hilt/flags#disable-install-in-check

Passing Activity Intent Data to ViewModel through Injection | by Elye | Mobile App Development Publication | Medium

Hilt를 사용한 종속 항목 삽입  |  Android 개발자  |  Android Developers