1. Context란?
- Android에서 앱의 현재 상태/환경 정보에 접근하는 통로
- Window로 비교하자면 앱 전체 환경이나 시스템 리소스에 접근하는 핸들 인터페이스 느낌
2. Context가 왜 필요한가?
- Android 앱은 리소스(이미지, 문자열, 레이아웃 등), 시스템 서비스(진동, 네트워크, 알림 등), 파일 시스템 등에 접근하려면 Android 시스템의 허가가 필요함
- Context가 위 요소들에 접근하는 통로(인터페이스)가 되어주는 것
3. Context로 할 수 있는 것들
context.getString(R.string.app_name) // 문자열 리소스 접근
context.getColor(R.color.primary) // 색상 리소스 접근
context.getSystemService(Context.VIBRATOR_SERVICE) // 시스템 서비스 접근
context.startActivity(intent) // 다른 화면 시작
context.getSharedPreferences("prefs", 0) // 로컬 저장소 접근
context.filesDir // 앱 파일 디렉토리 접근
※ Compose의 stringResource같은게 내부적으로 context를 사용해서 string을 얻는 것
단, stringResource는 @Composable 내에서만 사용 가능하고 context.getString은 어디서든 사용 가능
4. Context의 종류
- Context는 추상 클래스이고, 실제 구현채가 여러개 따로 있음(즉, Context는 하나만 있는 것이 아님)
1) applicationContext
- 앱이 살아있는 동안 유지되는 Context(앱 생명주기와 함께함)
- 주로 DB, SharedPreference, 네트워크/싱글톤 객체 초기화, 앱 전역 리소스/파일 접근 시 사용
2) activityContext
- Activity 자체가 Context
- 주로 Dialog 띄우기, Toast 띄우기, Layout Inflater, 다른 Activity 시작 시 사용
3) serviceContext
- Service 생명주기와 함께하는 Context
5. ContextWrapper
- 다른 Context를 감싸서 기능을 추가/변경하는 클래스
6. Context/ContextWrapper의 상속 구조
Context (추상 클래스)
├── ContextImpl (Android 내부의 실제 구현체)
└── ContextWrapper (ContextImpl을 내부 필드로 감싸서 위임하는 래퍼)
├── Application (앱 전체 단위 Context)
├── Service (백그라운드 작업 단위 Context)
└── ContextThemeWrapper (테마/스타일 기능 추가)
└── Activity (화면 단위 Context)
└── ComponentActivity
└── AppCompatActivity
7. Composable 내에서 Context 사용
val context = LocalContext.current 사용
Compose에서 사용 시 기본적으로 activityContext가 반환됨
8. 주의점
1) Context 사용 시 Memory Leak
- Activity Context는 Activity가 Destroy되는 시점에 메모리에서 해제되어야 함
- 하지만 만약 ViewModel, Singleton, Static변수 등의 Activity보다 수명이 긴 객체에 Activity Context를 저장하게되면 Activity가 파괴되어도 메모리에서 수거되지 않아 Memory Leak 발생
- 그러므로 오래 살아있는 객체에는 Context를 저장하지 않거나, 꼭 필요하다면 applicationContext를 사용