[Android] 쉽고 간편한 Dagger Hilt를 사용해 보자!

[Android] 쉽고 간편한 Dagger Hilt를 사용해 보자!

안녕하세요, 오늘은 Hilt에 대해 알아보려 합니다.

우선 알아보기 전에 의존성 주입이라는 개념에 대해 이해해야 하는데요

저의 이전 글을 참고하거나 구글링을 통해 개념을 조금 파악하시기 바랍니다

2021.08.24 - [Android Studio/Dependency] - 의존성 주입이란?

우선 Dagger2라는 의존성 주입 라이브러리는 러닝 커브가 높고 어렵습니다. 하지만 이런 Dagger2를 쉽게 사용할 수 있게 나온 것이 바로 Dagger Hilt입니다

Hilt는 여러분이 생각하는 것 그 이상으로 더 간단하고 이 글 한 개로도 충분이 사용하실 수 있을 겁니다

이 글에서는 간단하게 GithubApi를 Retrofit을 이용하여 호출하는 예시를 보여드립니다

깃허브 코드는 아래 링크에 있습니다

https://github.com/ParkSangSun1/Github_RxKotlin

@HiltAndroidApp

App.kt

import android.app.Application import dagger.hilt.android.HiltAndroidApp @HiltAndroidApp class App : Application() { private var instance: App? = null override fun onCreate() { super.onCreate() instance = this } }

먼저 Hilt를 사용하기 위해선 @HiltAndroidApp 어노테이션을 앱 시작할 때 실행시켜줘야 합니다. 때문에 Application()을 상속받은 App이라는 클래스에 어노테이션을 선언해주고 이 클래스를 AndroidManifest.xml에서 name으로 설정해줍니다

AndroidManifest.xml

이렇게 하면 준비운동은 끝이 납니다! 참 쉽죠?

@Module, @InstallIn(SingletonComponent::class), @Provides

외부 라이브러리 (Retrofit, Okhttp 등)는 Hilt가 어떻게 객체를 생성해야 하는지 방법을 모르기 때문은 @Modules를 사용해 우리가 알려줘야 합니다

@InstallIn(SingletonComponent::class)는 해당 모듈을 싱글턴으로 사용하겠다는 의미입니다

그러고 나서 클래스 안의 함수 앞에 @Provides, @Singletion 어노테이션을 붙여줍니다

NetworkModule.kt

@Module @InstallIn(SingletonComponent::class) object NetworkModule { @Provides @Singleton fun provideHttpClient(): OkHttpClient { return OkHttpClient.Builder() .readTimeout(10, TimeUnit.SECONDS) .connectTimeout(10, TimeUnit.SECONDS) .writeTimeout(15, TimeUnit.SECONDS) .addInterceptor(getLoggingInterceptor()) .build() } @Singleton @Provides fun provideRetrofitInstance( okHttpClient: OkHttpClient, gsonConverterFactory: GsonConverterFactory ): Retrofit { return Retrofit.Builder() .baseUrl(BASE_URL) .client(okHttpClient) .client(provideHttpClient()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addConverterFactory(gsonConverterFactory) .build() } @Provides @Singleton fun provideConverterFactory(): GsonConverterFactory { return GsonConverterFactory.create() } private fun getLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply { level = HttpLoggingInterceptor.Level.BODY } @Provides @Singleton fun provideGithubApiService(retrofit: Retrofit): GithubApi { return retrofit.create(GithubApi::class.java) } }

Retrofit을 사용하기 위한 NetworkModule입니다

RepositoryModule.kt

@Module @InstallIn(SingletonComponent::class) class RepositoryModule { @Provides @Singleton fun provideMainRepository( githubApi: GithubApi ) = MainRepository(githubApi) }

ViewModel에 Repository를 주입해서 사용하기 위한 Module

이곳에서 위에 선언한 NetworkModule의 provideGithubApiService함수를 이용해 GithubApi 의존성 주입을 받습니다

@HiltViewModel, @Inject

@Inject은 의존성 주입을 받겠다는 의미입니다. 사용할 때는 반드시 constructor()과 함께 사용해야 합니다.

위에서 RepositoryModule를 만들어주었고 반환형이 MainRepository인 provideMainRepository 함수를 선언했기 때문에 의존성 주입이 가능하게 됩니다

일반적인 클래스에서는 이렇게 @Inject를 사용해 의존성 주입을 받을 수 있지만 ViewModel에서는 @HiltViewModel이라는 어노테이션을 사용해야 합니다. 하지만 정말 이 한 줄만 추가로 사용하면 끝나기 때문에 그렇게 어렵지 않다는 점!

@HiltViewModel class MainViewModel @Inject constructor( private val mainRepository: MainRepository ) : ViewModel() { fun getUserInfo(owner: String) = mainRepository.getUserInfo(owner) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) .subscribe({ items -> items.forEach { println(it) } }, { e -> println(e.toString()) }) }

@AndroidEntryPoint

ViewModel까지 만들었다면 이제 이것을 사용할 activity가 필요할 겁니다

이때 ViewModel을 사용하는 activity에 @AndroidEntryPoint를 이용해 사용할 수 있습니다

Fragment에서 사용한다면 Fragment가 붙어있는 activity에 @AndroidEntryPoint를 붙여 사용할 수 있습니다

@AndroidEntryPoint class MainActivity : BaseActivity(R.layout.activity_main) { private val mainViewModel by viewModels() override fun init() { binding.activity = this } fun clickSearchBtn(view: View){ mainViewModel.getUserInfo(binding.name.text.toString()) } }

이렇게만 해줘도 Hilt를 이용해 쉽게 GithubApi를 호출해볼 수 있습니다!!

반응형

from http://asuhdevstory.tistory.com/66 by ccl(A) rewrite - 2021-12-29 09:02:03