Activity Context vs Application Context

홍성덕·2024년 8월 2일

이전 글을 통해서 Android Context 클래스에 대한 설명을 자세히 살펴보았다. 애플리케이션에 대한 전반적인 정보를 얻을 수 있는 Context를 통해서 리소스, DB, 프리퍼런스, 위치 서비스 같은 시스템서비스 등에 접근할 수 있다는 것도 알게 되었다.

Context는 Activity Context, Application Context 이렇게 크게 두가지로 나뉜다.

Activity Context

Activity Context는 액티비티에서 사용 가능하며, 액티비티의 생명주기와 연결되어 있다. 액티비티의 범위 내에서 Context를 전달할 때 사용한다.

Application Context

Application Context는 싱글톤 인스턴스로 애플리케이션의 생명주기와 연결되어 있다. 액티비티의 범위를 넘어선 Context를 전달할 때 사용한다.

주의할 점

1. 싱글톤 인스턴스 생성 시에는 Application Context 사용

// FavoriteDatabase.kt
@Database(entities = [DocumentEntity::class], version = 1)
abstract class FavoriteDatabase : RoomDatabase() {
    abstract fun documentDao(): FavoriteDao

    companion object {
        @Volatile
        private var INSTANCE: FavoriteDatabase? = null

        fun getDatabase(context: Context): FavoriteDatabase {
            return INSTANCE ?: synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    FavoriteDatabase::class.java,
                    "favorite-database"
                ).build()
                INSTANCE = instance
                instance
            }
        }
    }
}

// FavoriteFragment.kt
val dao = FavoriteDatabase.getDatabase(requireContext()).documentDao()

만약 위의 코드에서 Room.databaseBuilder에 context.applicationContext가 아닌 context를 전달한다면 Application Context가 아닌 Activity Context를 전달하게 된다.

Activity Context는 Activity가 종료되면 함께 사라지지만, 싱글톤 인스턴스는 애플리케이션 생명주기 동안 지속된다. Activity Context를 싱글톤 인스턴스를 생성할 때 전달하게 되면, 해당 Activity가 종료되었음에도 불구하고 해당 Activity의 Context를 계속 참조하고 있게 되어 메모리 누수가 발생한다.


2. ViewModel에 Acitivty Context 전달하면 안된다
이것도 싱글톤 인스턴스를 생성할 때 Activity Context를 전달하지 않는 이유와 비슷하다. ViewModel 인스턴스는 Activity보다 더 긴 생명주기를 가지고 있다. 그런데 Activity Context를 전달한다면 해당 Activity가 종료되었음에도 불구하고 해당 Activity의 Context는 메모리에서 해제되지 않아서 메모리 누수가 발생한다.


3. UI 컴포넌트를 사용할 때는 Activity Context 사용
앞선 설명에 따르면 Application Context가 만능일 것 같지만 그렇지 않다. Application Context는 Activity Context가 지원하는 것들을 지원하지 않는다.
그래서 예를 들어 Toast, Dialog 같은 UI 컴포넌트에 Application Context를 사용하면 IllegalStateException이 발생한다. UI 컴포넌트들은 어차피 Acitivty의 생명주기에 종속되기 때문에, Activity Context를 사용해주면 된다.


참고자료

profile
안드로이드 주니어 개발자

0개의 댓글