profile image

L o a d i n g . . .

반응형

이번에 사이드 프로젝트를 진행 하면서 HIlt를 한번 써볼 생각으로 적용하고 있는데,

 

이게 너무 복잡하고.. 빌드에러도 많이 났고.. 사실 아직까지도 어떻게 동작을 하는 것인지 모르겠네요..

 


Hilt는 안드로이드 앱에서 의존성 주입(Dependency Injection)을 쉽게 구현할 수 있도록 도와주는 라이브러리입니다. 

 

의존성 주입은 객체 간의 의존성을 더 이상 하드 코딩하지 않고 외부에서 주입하는 방식으로 구현합니다.

 이를 통해 코드의 유지보수성을 높이고, 테스트 용이성을 개선할 수 있습니다.

 

사실 적용하다가 실패하면 그냥 직접 생성해서 쓰고 말지! 라는 생각이 문득문득 듭니다..

 

Hilt는 Dagger2를 기반으로 만들어졌으며, Dagger2보다 더 쉽게 사용할 수 있도록 만들어졌습니다.

 Hilt는 앱의 전체 수명주기(Lifecycle-aware)를 고려하여 의존성을 관리합니다.

 액티비티, 서비스, 프래그먼트, 브로드캐스트 리시버 등 안드로이드 컴포넌트에서 의존성을 주입할 수 있습니다.

 

저 또한 네트워크 통신이나 DB접근 등에서 주입해서 쓸려고 합니다.

 

Hilt의 가장 큰 장점은 Hilt를 사용하면 코드를 간결하게 유지할 수 있으며, 안정적인 의존성 주입을 구현할 수 있습니다.


@Database(
    entities = [Entity.Content::class],
    version = 1,
    exportSchema = false
)

abstract class ContentRoomDatabase : RoomDatabase() {

    abstract fun contentDao(): ContentDao

    companion object {
        fun getInstance(context: Context): ContentRoomDatabase = Room
            .databaseBuilder(context, ContentRoomDatabase::class.java, "content_database.db")
            .addCallback(object : Callback() {
                override fun onCreate(db: SupportSQLiteDatabase) {
                    super.onCreate(db)
                }
            })
            .build()
    }
}

 

먼저 DB를 생성해주는 클래스를 만들어 줍니다.

이 부분은 Room 부분이며 구현은 구글링을 해보시면 아주 많은 자료들이 나옵니다.

 

class Entity {

    @Entity(tableName = "content_table")
    data class Content(
        @PrimaryKey(autoGenerate = true)
        val contentId: Int = 0,
        @ColumnInfo
        val contentText: String
    )
}

Room 구현에 있어 Entity를 만들어 줍니다. 

저는 PrimaryKey를 Int로 만들어 주었으며, autoGenerate를 true로 설정해줌으로써 데이터가 입력 시 Room에서 자체적으로 증가시켜 줍니다.

 

@Dao
interface ContentDao {

    @Query("SELECT * FROM content_table")
    fun sample(): Flow<List<Entity.Content>>
}

마지막으로 필요한 쿼리를 사용할 Dao 클래스를 만들어 줍니다.

쿼리를 알아야 하지만, 금방 익힐 수 있으며, 간단한 쿼리는 Room에서 어노테이션으로 도와줍니다

여기서 중요한건 꼭 @Dao 어노테이션을 추가시켜주어야 합니다.

 

이 부분에서 또 구글링을 통해 알게된 사실인데 리턴 타입이 flow면 굳이 suspend를 안붙여도 되는 것 같습니다..

이 부분도 더 학습과 확인이 필요하겠군요

 

@InstallIn(SingletonComponent::class)
@Module
object ContentDatabaseModule {

    @Singleton
    @Provides
    fun provideAppDatabase(@ApplicationContext context: Context): ContentRoomDatabase =
        ContentRoomDatabase.getInstance(context)

    @Provides
    fun provideNoteDAO(contentDataBase: ContentRoomDatabase): ContentDao {
        return contentDataBase.contentDao()
    }
}

설명하기 앞서 Hilt에 대한 기본적인 설정은 모두 해놓은 상태입니다. Application에 @HiltAndroidApp 등등 이미 추가 시켜놓았고 기본적인 사항이라 따로 설명하지 않겠습니다.

 

위에는 Hilt를 사용하기 위한 Module이며 DB생성 및 Dao를 사용하기 위한 것들이 정의되어 있습니다.

아직 제대로 익히지는 못했지만, hilt를 통해 주입되면서 자동으로 위 모듈이 실행되어 디비 생성과 Dao 정의 등..해주는 게 아닐까 싶은데 이 부분은 교육이 더 필요할 듯 합니다.

 

@InstallIn(SingletonComponent::class)
@Module
class ContentRepository @Inject constructor(
    private val contentDao: ContentDao
) {

    fun getSample(): Flow<List<Entity.Content>> {
        return contentDao.sample()
    }
}

이제 뷰모델에 직접 주입한 Repository를 만들어 줍니다. 

저는 이번에 Flow로 사용해볼 생각으로 Flow로 리턴하게 만들어 주었습니다.

 

@HiltViewModel
class MainViewModel @Inject constructor(
    private val contentRepository: ContentRepository
): ViewModel() {

    private val _sample = MutableLiveData<List<Entity.Content>>()
    private val sample : LiveData<List<Entity.Content>> = _sample

    fun sample() {
        viewModelScope.launch {
            contentRepository.getSample()
                .onStart {
                    
                }
                .onCompletion {
                    
                }
                .catch {
                    
                }
                .collect {
                    _sample.postValue(it)
                }
        }
    }
}

뷰모델에서 위에서 만든 Repository를 주입시켜 주면 바로 repository에 저장된 함수들을 호출 할 수 있습니다

저는 Flow로 만들었기에 viewModelScope로 감싸주었고 Flow 연산자를 통해 받게끔 하였습니다

 

받은 데이터는 LiveData로 받아서 처리할 생각으로 해두었습니다.


분명 Hilt를 한번 셋팅해두면 다음 개발이나 유지보수 측면에서 편해보일지 모르겠지만, 수정해야할 경우 또 복잡해지는 느낌이 없지 않아있어 작은 프로젝트에는 굳이 써야할 필요가 있을까~ 라는 생각이 드네요

 

그리고 Hilt에서는 모든 어노테이션들이 중요하며 필수적입니다. 안할 시 빌드 에러가 뜨더군요

 

익혀두면 좋은 Hilt지만 너무 복잡하네요. 심지어 이걸 구글에서 Dagger를 쉽게 쓰라고 만들어 준건데 Dagger는 또 얼마나 복잡하길래...

반응형
복사했습니다!