getApplication () 대 getApplicationContext ()


417

거래는 무엇입니다 : 우리가 간다, 그래서 여기에이에게 만족 대답을 찾을 수 없습니다 Activity/Service.getApplication()Context.getApplicationContext()?

우리의 응용 프로그램에서 둘 다 동일한 객체를 반환합니다. 에서 ActivityTestCase그러나, 응용 프로그램을 조롱하는 것 getApplication()모의로 돌아와,하지만 getApplicationContext여전히 다른 컨텍스트 인스턴스 (안드로이드 주입 한)을 반환합니다. 그게 버그 야? 의도적인가요?

나는 처음부터 차이점을 이해하지 못합니다. 테스트 스위트 외부에서 두 통화가 다른 객체로 돌아올 수있는 경우가 있습니까? 언제 그리고 왜? 또한, 왜 getApplication정의 Activity하고 Service, 그러나에 Context? 언제 어디서나 유효한 응용 프로그램 인스턴스가 없어야 합니까?


8
좋은 질문. 테스트 항목은 (알다시피) 미스터리입니다. 그러나 앱에서 객체를 명시 적으로 만들지 않으면 이 두 메서드 호출에서 차이점이 나타나는지 궁금합니다 Application.
Christopher Orr

답변:


366

매우 흥미로운 질문입니다. 나는 이것이 의미 론적 의미라고 생각하며 역사적인 이유 때문일 수도 있습니다.

현재 안드로이드 활동 및 서비스 구현에, 비록 getApplication()getApplicationContext()같은 개체를 반환이 항상 (특정 공급 업체의 구현, 예를 들어)의 경우가 될 것이라는 보장은 없습니다.

따라서 매니페스트에 등록한 응용 프로그램 클래스를 원한다면 응용 프로그램 인스턴스 (테스트 프레임 워크에서 분명히 경험 한 응용 프로그램 인스턴스)가 아닐 수 있으므로 응용 프로그램을 호출 하여 응용 프로그램에 캐스트 해서는 안됩니다getApplicationContext() .

getApplicationContext()처음에 존재합니까?

getApplication()getApplicationContext()Context 클래스에서 선언되는 반면 Activity 클래스와 Service 클래스에서만 사용할 수 있습니다 .

그것은 실제로 한 가지 의미입니다. 브로드 캐스트 리시버에서 코드를 작성할 때 컨텍스트가 아니지만 onReceive 메소드에 컨텍스트가 제공되는 경우에만 호출 할 수 있습니다 getApplicationContext(). 또한 BroadcastReceiver에서 응용 프로그램에 액세스 할 수있는 것은 아닙니다.

Android 코드를 보면 첨부 할 때 활동에 기본 컨텍스트 및 애플리케이션이 수신되고 서로 다른 매개 변수라는 것을 알 수 있습니다. getApplicationContext()에 전화를 위임합니다 baseContext.getApplicationContext().

한 가지 더 : 설명서에는 대부분의 경우 Application을 서브 클래스 화 할 필요가 없다고 말합니다.

일반적으로 서브 클래스가 필요하지 않습니다 Application. 대부분의 상황에서 정적 싱글 톤은보다 기능적인 방식으로 동일한 기능을 제공 할 수 있습니다. 싱글 톤에 글로벌 컨텍스트가 필요한 경우 (예 : 브로드 캐스트 리시버 등록) 싱글 톤을 처음 구성 할 때 Context내부적으로 사용 하는 기능을 검색 할 수 있습니다 Context.getApplicationContext().

나는 이것이 정확하고 정확한 답변이 아니라는 것을 알고 있지만 여전히 귀하의 질문에 대답합니까?


89
@ Piwaï : 의사의 말을 듣지 마십시오. 서브 클래 싱 android.app.Application은 완전히 도움이됩니다. 예를 들어 데이터베이스를 초기화하는 데 끝없는 문제가있었습니다. 일단 들어가면 Application.onCreate매력처럼 일했습니다. 이제 모든 시스템 전체 초기화를 수행 Application하고 없이는 다른 앱을 작성하지 않습니다.
Martin

9
@Martin 문서를 듣지 않으면 일반적으로 코드가 미래에 깨질 수 있으며, 심지어 지금 예기치 않은 조건에서 이식성이 떨어지고, 성능이 저하되거나, 플랫폼 개발자가 유익한 변경을하지 못하도록 방지 할 수 있음을 의미합니다. 문서가 아닌 현재 구현에만 기반). 나는 이것이 꽤 나쁜 행동이고 꽤 나쁜 조언이라고 생각합니다.
Palec

17
@Palec :“일반적으로 응용 프로그램을 서브 클래 싱 할 필요가 없습니다.” — 힌트 일뿐입니다. 나는 여전히 공식적으로 문서화 된 기능을 의도 된 방식으로 사용합니다. — 나는 처음에 그“정적 싱글 톤”을 사용했고 그것들은 고통 스럽습니다. — 게으른 초기화에는 문제가 있습니다. 특히 계측 테스트와 함께 사용하는 경우. — 모듈화를위한 싱글 톤이 있지만 android.app.Application 서브 클래스의 onCreate에서 블록으로 인스턴스화합니다. — 매력처럼 작동합니다.
Martin

9
@Martin 나는 분명히했다 : 나의 반응은 첫 문장에만 관심이있다. "문서를 듣지 마십시오." 이것은 일반적으로 매우 위험한 조언입니다. 그러나“이것은 단지 힌트 일뿐입니다.이 경우에는 문서를 무시할 수 있습니다. 이유가 있으면 하나만 보여 드리겠습니다 ...”는 나에게 절대적으로 괜찮습니다.
Palec

3
"컨텍스트가 아니지만 onReceive 메소드에 컨텍스트가 제공되는 브로드 캐스트 리시버에서 코드를 작성할 때 getApplicationContext () 만 호출 할 수 있습니다. 이는 또한 BroadcastReceiver에서 애플리케이션에 대한 액세스 권한이 보장되지 않음을 의미합니다. " . 따라서 BroadcastReceiver의 응용 프로그램 클래스에 액세스하려면 어떻게해야합니까?
Dr.jacky

30

getApplication()와 비교하십시오 getApplicationContext().

getApplicationApplication전역 응용 프로그램 상태를 관리하고 onLowMemory()및과 같은 일부 장치 상황에 응답 할 수 있는 객체를 반환합니다 onConfigurationChanged().

getApplicationContext전역 응용 프로그램 컨텍스트를 반환합니다. 다른 컨텍스트와의 차이점은 예를 들어 활동이 종료되면 Android에서 활동 컨텍스트가 파괴되거나 사용 불가능하게 될 수 있다는 것입니다. Application 컨텍스트는 Application 객체가 존재하는 동안 계속 사용할 수 Activity있으므로 ( 특정에 묶이지 않음 ) 장기간 사용할 수 있고 일시적인 UI 객체와 무관하게 컨텍스트를 필요로하는 알림 과 같은 경우에이를 사용할 수 있습니다.

나는 그것이 동일한 지 아닌지에 관계없이 코드가 무엇을하고 있는지에 달려 있다고 생각합니다. 그러나 정상적인 사용에서는 코드가 다를 것으로 기대합니다.


19
그러나이 Application 이고 , A는 Context(그것이 상속), 런타임시에, 두 방법은 동일한 인스턴스를 반환한다. 차이점은 무엇입니까?
Matthias

3
차이점은 범위입니다. 활동이 매우 짧은 시간 동안 만 사용 중일 수 있지만 애플리케이션이 많은 활동으로 구성 될 수 있기 때문에 애플리케이션 컨텍스트는 활동 컨텍스트보다 훨씬 오래 유효합니다. 활동 컨텍스트는 첫 번째 활동이 시작될 때 시작하여 마지막 활동이 끝나는 기간 동안 지속됩니다. 그것들은 모두 컨텍스트이지만, 하나는 더 오래 지속되고 변경되지 않지만 다른 인스턴스는 수명이 짧으며 인스턴스마다 다른 컨텍스트가있을 수 있습니다.
RivieraKid

16
내 질문을 잘못 읽고 있다고 생각합니다. 나는 Activity문맥과 맥락 의 차이를 요구하지 않습니다 Application. 나는 Application(전세계적이고 독특한 응용 프로그램 컨텍스트 인)와 getApplicationContext반환 되는 것의 차이점을 숙고하고 있습니다. 후자는 안드로이드 1.6 이전에는 작동하지 않았다. 항상 반환하는 데 사용됩니다 null.
Matthias

1
@ Matthias 내 의견으로는 여전히 관련이 있습니다. Context는 Android 시스템 자체에 의해 주입 (구현)되는 반면 Application은 Context를 상속하고 확장합니다. 응용 프로그램 클래스는 쉽게 조롱 할 수 있습니다 (당신이 말했듯이) 응용 프로그램 클래스가 테스트 프로젝트에서 "매직"을 수행하여 주입 된 컨텍스트를 무시할 수 있음을 보여주는 것이 안전하지 않습니까?
Audrius

3
다시 오세요? 죄송합니다. 그래도 내 질문에 어떻게 대답하는지 모르겠습니다.
Matthias

30

컨텍스트 랩핑과 관련이있는 것 같습니다. 에서 파생 된 대부분의 클래스 Context는 실제로 ContextWrapper는 래퍼에 의해 변경 될 수있는 본질적으로 다른 컨텍스트에 위임됩니다.

컨텍스트는 조롱 및 프록시를 지원하는 일반적인 추상화입니다. 많은 컨텍스트가과 같은 수명이 제한된 개체에 바인딩되어 있기 때문에 Activity향후 알림 등록과 같은 목적으로 수명이 긴 컨텍스트를 얻는 방법이 필요합니다. 에 의해 달성됩니다 Context.getApplicationContext(). 논리적 구현은 전역 Application객체 를 반환하는 것이지만 컨텍스트 구현이 대신 적절한 수명을 가진 래퍼 또는 프록시를 반환하는 것을 막는 것은 없습니다.

활동 및 서비스는보다 구체적으로 Application객체 와 연관됩니다 . 이것의 유용성은, 저는 믿습니다, 당신이 만들어에서 파생 된 매니페스트 사용자 정의 클래스에 등록 할 수 있다는 Application그 확신 할 수 Activity.getApplication()또는 Service.getApplication()당신이 당신의 파생으로 캐스팅 할 수있는 특정 유형의 특정 오브젝트 돌아갑니다 Application무엇을위한 클래스와 사용 사용자 정의 목적.

즉, getApplication()반환 보장 Application하면서, 객체를 getApplicationContext()대신 프록시를 반환 무료입니다.


"컨텍스트가 조롱과 프록시를 지원하는 일반적인 추상화"라고 말할 때 정확히 "프록시"라는 것은 무엇을 의미합니까? 저에게 몇 가지 언급을 말씀해 주시겠습니까? 전체 컨텍스트가 상당히 복잡하다는 것을 알았습니다.
Tiago

@Tiago이 답변은 더 잘 이해하는 데 도움이됩니다. stackoverflow.com/questions/10641144/…
superuser

-13

질문에 대답하기 위해 getApplication ()은 Application 객체를 반환하고 getApplicationContext ()는 Context 객체를 반환합니다. 본인의 관찰에 따라 두 컨텍스트가 동일하다고 가정합니다 (즉, Application 클래스가 후자의 함수를 호출하여 기본 클래스의 컨텍스트 부분을 채우거나 동등한 조치가 발생하는 장면 뒤). 컨텍스트가 필요한 경우 어떤 함수를 호출하는지는 중요하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.