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를 사용