Android의 Context란?
Application, Service, Activity 모두 Context를 상속 했다는 사실 알고계셨나요?
공식문서에 나와있는 Context의 개요를 확인해보면,
애플리케이션 환경에 대한 전역정보가 컨텍스트로 연결됩니다. Context는 구현이 Android 시스템에 의해 제공되는 추상 클래스입니다. 애플리케이션 별로 리소스 및 클래스에 대한 접근은 물론 Activity의 실행, 브로드 캐스팅 및 Intent수신과 같은 애플리케이션 레벨에 대한 호출을 허용합니다. |
쉽게 말해 Context를 이용하면 getPackageName(), getResource(), startActivity(), startService(), getSystemService()와 같이 시스템 레벨의 정보를 얻을수 있는 메소드를 쓸수 있습니다. 또한 Context는 시스템에 대한 리소스 확인, 데이터베이스 및 환경 설정에 대한 액세스 확보 등과 같은 서비스를 제공합니다. Android 애플리케이션 내에 다수의Activity들이 존재할 수 있으며, 이것은 애플리케이션이 현재 실행중인 환경에 대한 핸들과 같습니다. 맨위에서 말씀 드렸듯이 Activity 객체는 Context 객체를 상속받습니다. 즉 Activity는 애플리케이션의 특정자원, 클래스,애플리케이션의 환경 정보에 대해 접근할 수 있게 됩니다.
Application Context vs Activity Context
Application Context는 애플리케이션과 관련되어 있고 애플리케이션이 살아있는 동안 변경되지 않습니다. 그러므로 싱글톤이며 getApplicationContext()를 통해 Activity에서 접근할 수 있는 인스턴스 입니다. 이 Context는 애플리케이션의 생명주기와 관련되어있기 때문에 현재 Context와 분리된 어떤 Context가 필요하거나, 현재 Activity Scope을 벗어난 작업을 할때 필요합니다.
어떤 싱글톤 객체를 만들어야하고 해당 객체에 항상 Context가 필요한 경우에 Application Context를 전달하면 됩니다.
Application Context에 Activity를 참조하게 되면 Activity가 부서지더라도 참조가 유지되므로, Activity가 GC(가비지 콜렉팅)되지 않으므로 메모리 누수가 발생합니다.
다른 Context보다 가장 오래 보존될만한 Context가 필요할때만 getApplicationContext()를 사용합시다.
Activity Context는 액티비티와 관련이 있고, 액티비티가 부서지면 컨텍스트도 같이 부서집니다. 하나의 애플리케이션에서 여러 액티비티가 존재 할 수 있는데 때로는 특정 Activity Context를 다룰일이 생깁니다. 예를 들어 새로운 액티비티를 실행한다면, 액티비티(컨텍스트)가 필요합니다. 새로 띄워진 액티비티는 이전 액티비티와 연관되어진체로 액티비티 스택에 보관됩니다. Application Context를 이용하여 새로운 액티비티를 띄울수도 있지만 그럴경우 반드시 Intent.FLAG_ACTIVITY_NEW_TASK 플래그를 설정 해주어야합니다.
Context 얻기
View.getContext() :
현재 뷰가 가지고 있는 context를 반환하는데, 일반적으로는 Activity에서 View를 띄우기 때문에 Activity의 Context가 된다.
Activity.getApplicationContext() :
애플리케이션 전체의 컨텍스트를 반환합니다. 현재 액티비티뿐만 아니라 애플리케이션의 수명주기와 관련된 컨텍스트가 필요한 경우 Activity Context대신 이 값을 사용하면 됩니다.
ContextWrapper.getBaseContext() :
다른 컨텍스트로부터 어떤 컨텍스트에 접근해야하는경우에 ContextWrapper를 씁니다. ContextWrapper 내부에서 참조 된 Context는 getBaseContext ()를 통해 액세스됩니다.
Context를 잘못 쓰는 경우
Application Context는 Activity가 하는 모든 것을 지원하는 은총알 같은 Context는 아닙니다. Application Context로는 대부분 GUI(화면, View, 등) 작업은 할 수 없습니다. Activity 만 가능하죠. 예를 들어 Application Context를 이용하여 AlertDialog를 띄우려고 한다면 다음과 같은 에러를 볼 수 있습니다.
java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
그런데 Toast는 Application Context를 이용해도 아무 문제가 없이 잘 뜹니다.Toast의 경우 특정 액티비티에 연관된 윈도우에 속하지 않고, 자신만의 윈도우를 생성하기 때문입니다.
또한 어떠한 Context를 Scope이 더 큰 Context나 어떤 무언가가 참조하고 있으면 GC 되지 않고 많은 메모리를 잃게 되므로 조심하지 않으면 메모리 누수가 쉽게 발생할 수 있습니다.
1개의 댓글
성빈 · 2023년 6월 27일 5:43 오후
정리 감사합니다!