Context 란
Application/Activity의 현재 정보, 흐름을 담고 있는 객체이며, 새로 생성된 객체에게 해당 실행 맥락을 제공한다.
- Application 환경에 관한 전체 정보를 받을 수 있는 추상 클래스로 Activity, Brodcast Receiver, Service를 시작할 때도 사용되고 리소스에 접근할 때도 Context가 사용됨
- Application과 관련된 정보에 접근 또는 Application과 연관된 시스템 레벨의 함수를 호출하고자 할 때 Context 필요
- 안드로이드는 Application 관련 정보를 ActivityManagerService에서 관리
- Application과 관련된 정보에 접근하려고 할 때 식별자가 필요한데, 그 역할을 하는 것도 Context
Context의 구분(종류)
Application Context
- Application의 맥락을 담고 있는 Context
- 싱글톤 객체임
- Activity에서 Context로 제공을 요청
- 해당 Application과 생명 주기가 같고, Application 전역에서 유효
- Application이 시작될 때 생성되고, 종료될 때 소멸
applicationContext
Application Context = getApplicationContext() = getApplication()
- Application의 생명 주기 내내 진행되는, 전역적인 작업 등의 Context로 적합
- ActivityViewModel 클래스를 상속받는 viewModel을 사용하는 경우, ViewModel의 수명 주기가 Activity의 생명 주기보다 길기 때문에 사용할 수 있다
- Activity에서 라이브러리를 초기화해야 할 경우 사용할 수 있다
- Activity보다 생명 주기가 길기 때문에 Application Context를 사용한 작업이 진행된 후 메모리에서 Garbage Collection이 진행되지 않는다
- Dialog 등의 UI를 표시하는 작업은 비효율적이거나, 아예 불가능하다
- Dialog는 Activity의 수명 주기 내에서 충분히 처리할 수 있는 작업
- Toast는 표시 가능
Activity Context
- 실행중인 Activity의 맥락을 담고 있는 Context
- 해당 Activity와 생명 주기가 같고, Activity 내에서만 유효
- Activity가 시작될 때 생성되고, 종료될 때 소멸
this = baseContext
Activity Context = this = getBaseContext()
- this 또는 baseContext는 현재 Activity 자신을 가리킨다.
- Activity의 생명 주기 내에서 수행하는 작업에 제공되는 Context로 적합하다.
- Intent, Toast 등에서 사용하기 적합
- Fragment에서의
getContext()와 requireContext()
- 가장 큰 차이는 nullable 여부
- requireContext : NonNull
- getContext : Nullable
- 반환 : Activity Context
단지 반환값의 차이로, context를 불러올 수 없는 경우 null을 반환하는지, 아니면 throw를 통해 exception을 발생시키는지에 대한 차이이다. (동일한 코드지만 exception을 일으키느냐, null을 반환하느냐)
Null이 아님을 보장해준다고 생각하기 쉬운 requireContext()를 쓰더라도 터지지 않는 것은 아님
예외처리 구문을 이용하든, if(context == null)을 이용하든 context는 특정 상황에서 null이 될 수 있음을 기억하고 (스레드나 코루틴을 통한 비동기적인 코드를 작성하는 측면) 적절한 처리가 필요하다.
※ Context가 들어가는 자리에 적절하지 않은 Context를 사용한다면 메모리 누수가 발생할 수 있다.
ex) Application Context를 참조하여 싱글톤 객체를 생성해야 할 때 Activity Context를 참조하여 생성하게 된다면, Garbage Collector가 Activity Context를 수거하지 못하여 메모리 누수가 발생
Activity의 생명 주기 내에서 처리할 수 있는 작업은 (Intent, Toast, Dialog 등) this, baseContext 와 같은 Activity Context를 사용하여 작업을 처리하고, ViewModel 등의 Application과 생명 주기를 공유하거나 단일 Activity의 생명 주기보다 긴 작업을 하는 경우에는 Application Context를 사용해야 함
참고