반응형
Application Context의 적절한 사용
- Application의 Context는 애플리케이션이 실행되는 동안 메모리에 유지됩니다.
따라서 전역적으로 사용되거나 장기적인 참조가 필요한 객체들에 적합하며, UI와 관계없는 작업에서 안전하게 사용할 수 있습니다. - Application 단의 Context를 확장 함수에서 사용하게 되면, 단위 테스트를 수행하기 어려워질 수 있습니다.
Context에 의존하는 코드는 테스트에서 모의(Mocking) 처리가 필요하며, 이는 테스트의 복잡성을 높입니다.
1. Application Context
를 사용하는 것이 적절한 경우
- 장기적으로 유지되는 객체:
- 장기적으로 유지되거나 전역적으로 사용되는 객체에서
Context
가 필요할 때는Application Context
를 사용하는 것이 안전합니다. 예를 들어, 싱글톤 객체,Service
, 데이터베이스 관리 객체, 네트워크 관련 객체 등은Application Context
를 사용하는 것이 적합합니다.
- 장기적으로 유지되거나 전역적으로 사용되는 객체에서
- UI와 무관한 작업:
- 리소스에 접근하거나, 시스템 서비스(예:
AlarmManager
,ConnectivityManager
)에 접근하는 것과 같이 UI와 관계없는 작업을 수행할 때는Application Context
를 사용해도 문제가 없습니다.
- 리소스에 접근하거나, 시스템 서비스(예:
- 외부 구성 요소에서
Context
가 필요할 때:- 외부 라이브러리나 유틸리티 클래스가
Context
를 필요로 할 때, 이들이 장기적으로 사용된다면Application Context
를 전달하는 것이 바람직합니다. 이는 메모리 누수를 방지하는 데 도움이 됩니다.
- 외부 라이브러리나 유틸리티 클래스가
2. Application Context
를 사용하는 것이 부적절한 경우
- UI 관련 작업:
Application Context
는 UI 요소를 생성하거나 관리하는 데 적합하지 않습니다. 예를 들어,LayoutInflater
로 뷰를 인플레이트하거나,Toast
메시지를 띄우는 등의 작업에서Application Context
를 사용하는 경우, UI의 스타일이나 테마가 올바르게 적용되지 않을 수 있습니다. 특히,Activity
의 생명 주기와 밀접한 UI 관련 작업에서는Activity
의Context
를 사용해야 합니다.
- 테마 및 스타일 적용이 필요한 경우:
Activity
는Application
과 달리 특정 테마와 스타일을 가질 수 있습니다.Activity
의Context
를 사용하면 해당 테마와 스타일이 적용된 UI 요소를 생성할 수 있지만,Application Context
를 사용하면 기본 테마가 적용될 수 있습니다. 예를 들어, 대화상자(AlertDialog
)를 띄우는 경우,Application Context
를 사용하면 기본 시스템 테마가 적용되므로Activity
의Context
를 사용하는 것이 적절합니다.
- 뷰 또는 UI 컴포넌트의 생성(=뷰의 생성 및 관리 작업):
View
또는UI Component
는 특정Activity
나Fragment
에 속해 있으므로, 이들을 생성하거나 관리할 때는 해당Activity
또는Fragment
의Context
를 사용하는 것이 맞습니다.Application Context
를 사용하면 뷰가 잘못된 컨텍스트에 바인딩되어 의도한 대로 동작하지 않을 수 있습니다.
Application Context의 DI(hilt) 설정
1. Application 단의 Context 주입
1.1. @HiltAndroidApp 주석 추가
Application 클래스를 Hilt로 설정합니다:
@HiltAndroidApp
class MyApp : Application() {
// Application 단에서 필요한 설정들
}
1.2. Context 제공자 모듈 작성
Hilt 모듈을 통해 Application Context를 제공하도록 설정합니다:
@Module
@InstallIn(SingletonComponent::class)
object AppModule {
@Provides
@Singleton
fun provideContext(@ApplicationContext context: Context): Context {
return context
}
}
2. 싱글톤 객체를 활용한 전역 Context
관리
클래스에서 Context
를 주입받고 싶지 않다면,
다른 방법으로 Application
단의 Context
를 전역적으로 관리하면서도 코드의 재사용성을 높일 수 있습니다.
이 경우, 전역적으로 사용할 수 있는 Context
를 제공하는 싱글톤 객체를 만들어 확장 함수에서 활용할 수 있습니다.
전역적으로 Context
를 관리하기 위해 싱글톤 패턴을 사용할 수 있습니다. 이 방법을 사용하면 Context
를 직접 주입하지 않고도 쉽게 접근할 수 있습니다.
2.1. AppContextProvider
싱글톤 객체 생성
object AppContextProvider {
lateinit var context: Context
private set
fun init(context: Context) {
this.context = context
}
}
AppContextProvider
는 애플리케이션 시작 시 Context
를 초기화하고, 그 이후에는 전역적으로 접근할 수 있도록 합니다.
2.2. Application
클래스에서 초기화
애플리케이션 클래스에서 AppContextProvider
를 초기화합니다:
@HiltAndroidApp
class MyApp : Application() {
override fun onCreate() {
super.onCreate()
AppContextProvider.init(this)
}
}
2.3. Application Context 접근
이제 Context
를 직접 주입받지 않고, 싱글톤 객체를 통해 전역적으로 접근할 수 있습니다:
AppContextProvider.context.resources.displayMetrics
고려사항
- 싱글톤 패턴의 신중한 사용:
- 싱글톤 패턴을 사용하면
Context
를 전역적으로 사용할 수 있어 편리하지만, 잘못 사용할 경우 여전히 메모리 누수 등의 문제가 발생할 수 있습니다. 특히,Activity
나Fragment
의Context
를 사용해야 하는 경우에는 이 방법을 사용하지 않는 것이 좋습니다.
- 싱글톤 패턴을 사용하면
- 유연성의 제한:
- 전역적으로
Application
의Context
에만 접근할 수 있으므로, 특정 UI 요소와 관련된Context
가 필요한 경우에는 이 방법이 적절하지 않을 수 있습니다.
- 전역적으로
- 테스트 가능성:
- 전역 싱글톤 객체를 사용하면 단위 테스트에서
Context
를 모의하기가 어려워질 수 있습니다. 단위 테스트에서 이 싱글톤 객체를 사용하는 코드를 테스트하기 위해서는 추가적인 설정이 필요할 수 있습니다.
- 전역 싱글톤 객체를 사용하면 단위 테스트에서
이 방법을 통해 DimensionConverter
클래스에서 Context
를 직접 주입받지 않고도 확장 함수를 전역적으로 사용할 수 있습니다. 하지만 이 접근 방식이 모든 경우에 최선이 아닐 수 있으므로, 프로젝트의 요구 사항에 맞게 선택하는 것이 중요합니다.
반응형