일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 플러터 설치 2022
- 자바 다형성
- 스택 자바 코드
- 멤버변수
- 안드로이드 os 구조
- 안드로이드 유닛 테스트
- 안드로이드 레트로핏 사용법
- rxjava hot observable
- 서비스 쓰레드 차이
- 안드로이드 유닛 테스트 예시
- 스택 큐 차이
- ANR이란
- 안드로이드 레트로핏 crud
- 안드로이드 라이선스 종류
- 2022 플러터 안드로이드 스튜디오
- ar vr 차이
- 클래스
- Rxjava Observable
- rxjava cold observable
- 안드로이드 라이선스
- 2022 플러터 설치
- android ar 개발
- 안드로이드 유닛테스트란
- jvm 작동 원리
- 큐 자바 코드
- jvm이란
- android retrofit login
- 객체
- rxjava disposable
- 서비스 vs 쓰레드
- Today
- Total
나만을 위한 블로그
[Android] getApplicationContext() vs XXXActvity.this의 차이 본문
인텐트를 통해 액티비티를 이동하거나, 토스트와 다이얼로그 같은 기본적인 창부터 다양한 곳에 이르기까지 사용되는 요소들이 2개 있다. getApplicationContext() 혹은 액티비티명.this다.
평소에는 별 생각 없이 액티비티명.this를 주로 사용했는데 문득 이 2개의 차이가 무엇인지 궁금해져서 정리해 기록하고자 글을 쓰게 됐다. 이 글이 무조건 확실하진 않고 공부하면서 기록하고자 남기는 글이니 무조건 믿지는 말자
결론만 보려면 맨 밑으로
먼저 스택오버플로우에선 이렇게 말하고 있다. 구글 번역기가 액티비티를 활동으로 번역했기 때문에 그 부분을 액티비티로 고쳐쓴 걸 말고는 번역된 문장 그대로 가져왔다.
Application context is associated with the application and will always be the same throughout the life of application ; it does not change. So if you are using Toast, you can use application context or even activity context (both) because Toast can be displayed from anywhere within your application and is not attached to a specific window. But there are many exceptions. One such exception is when you need to use or pass the activity context.
- 애플리케이션 컨텍스트는 앱과 연결되어 있으며 앱 수명 내내 항상 동일합니다. 변경되지 않습니다. 따라서 Toast를 사용하는 경우 Toast는 애플리케이션 내 어디에서나 표시될 수 있고 특정 창에 연결되지 않기 때문에 애플리케이션 컨텍스트 또는 액티비티 컨텍스트 (둘 다)를 사용할 수 있습니다. 그러나 많은 예외가 있습니다. 이러한 예외 중 하나는 액티비티 컨텍스트를 사용하거나 전달해야 하는 경우입니다.
Activity context is associated with the activity and can be destroyed if the activity is destroyed ; there may be multiple activities (more than likely) with a single application. And sometimes you absolutely need the activity context handle. For example, should you launch a new Activity, you need to use activity context in its Intent so that the newly launched activity is connected to the current activity in terms of activity stack. However, you may also use application's context to launch a new activity, but then you need to set flag Intent.FLAG_ACTIVITY_NEW_TASK in intent to treat it as a new task.
- 액티비티 컨텍스트는 액티비티와 연관되며, 액티비티가 소멸되면 소멸될 수 있습니다. 단일 응용 프로그램에 여러 액티비티가 있을 수 있습니다. 때로는 액티비티 컨텍스트 핸들이 절대적으로 필요합니다. 예를 들어 새 액티비티를 시작하는 경우, 새로 시작된 액티비티가 액티비티 스택 측면에서 현재 액티비티에 연결되도록 해당 인텐트에서 액티비티 컨텍스트를 사용해야 합니다. 그러나 애플리케이션의 컨텍스트를 사용하여 새 액티비티를 시작할 수도 있지만, 새 작업으로 처리하려면 Intent.FLAG_ACTIVITY_NEW_TASK 플래그를 설정해야 합니다.
Application Context는 getApplicationContext()를 말하는 것 같고, Activity Context는 XXXActivity.this를 말하는 것 같다.
Application Context는 응용 프로그램(앱)과 연결돼 있으며 앱 내의 어떤 화면에서든 표시될 수 있는 토스트의 경우 Application Context와 Activity Context 둘 다 사용할 수 있다.
Activity Context는 액티비티가 사라질 때 같이 사라지고, Application Context로 새 액티비티를 시작할 경우 인텐트에 플래그를 하나 설정해야 한다.
그러니까 getApplicationContext()를 쓰면 컨텍스트가 앱이 죽기 전까지 사라지지 않고, XXXActivity.this를 쓰면 액티비티가 사라질 때 컨텍스트도 같이 사라진다는 뜻인데, 두 경우를 나눠놓은 이유가 뭘까?
다른 글에서는 아래처럼 설명하고 있다.
stackoverflow.com/questions/16141369/difference-between-getapplicationcontext-and-classname-this
ActivityName.this refers to activity context. getApplicationContext() refers to the application context.
Most of the times it is better to use activity context.
- XXXActivity.this는 액티비티 컨텍스트를 나타낸다. getApplicationContext()는 애플리케이션 컨텍스트를 참조한다. 대부분의 경우 액티비티 컨텍스트를 쓰는 것이 낫다.
Here are reasons why not to use getApplicationContext() wherever you go:
- 어딜 가든 getApplicationContext()를 사용하지 않는 이유는 다음과 같습니다
1. It's not a complete Context, supporting everything that Activity does. Various things you will try to do with this Context will fail, mostly related to the GUI.
- 액티비티가 수행하는 모든 것을 지원하는 완전한 컨텍스트가 아닙니다. 이 컨텍스트로 수행하려는 다양한 작업은 대부분 GUI와 관련된 실패를 합니다.(에러가 발생한다는 뜻으로 이해했다)
2. It can create memory leaks, if the Context from getApplicationContext() holds onto something created by your calls on it that you don't clean up. With an Activity, if it holds onto something, once the Activity gets garbage collected, everything else flushes out too. The Application object remains for the lifetime of your process.
- getApplicationContext()의 Context가 정리하지 않은 호출에 의해 생성된 무언가를 보유하면 메모리 누수가 발생할 수 있습니다. Activity를 사용하면 무언가를 보유하고 있으면 Activity가 가비지 수집될 경우 다른 모든 것도 flush됩니다. Application 개체는 프로세스 수명 동안 유지됩니다.
getApplicationContext()는 앱이 실행되는 동안 유지되기 때문에 메모리 누수가 발생할 수 있다고 이해했다.
그리고 Activity Context를 쓰면 액티비티가 가비지 수집, 즉 사라질 경우에 이 액티비티와 관련된 모든 것도 같이 정리된다는 뜻으로 이해했다.
다른 글도 찾아봤다. 본문의 파란색은 답변 본문에서 링크로 되어있던 부분이다.
stackoverflow.com/questions/4128589/difference-between-activity-context-and-application-context
They are both instances of Context, but the application instance is tied to the lifecycle of the application, while the Activity instance is tied to the lifecycle of an Activity. Thus, they have access to different information about the application environment.
If you read the docs at getApplicationContext it notes that you should only use this if you need a context whose lifecycle is separate from the current context. This doesn't apply in either of your examples.
The Activity context presumably has some information about the current activity that is necessary to complete those calls. If you show the exact error message, might be able to point to what exactly it needs.
But in general, use the activity context unless you have a good reason not to.
- 둘 다 Context의 인스턴스지만 애플리케이션 인스턴스는 애플리케이션의 라이프 사이클에 연결되어 있고, Activity 인스턴스는 액티비티 라이프 사이클에 연결되어 있습니다. 따라서 애플리케이션 환경에 대한 다양한 정보에 액세스 할 수 있습니다. getApplicationContext에서 문서를 읽으면 라이프 사이클이 현재 컨텍스트와 분리된 컨텍스트가 필요한 경우에만 이것을 사용해야 한다는 점에 유의하십시오. 이것은 귀하의 예에 적용되지 않습니다.
액티비티 컨텍스트에는 해당 호출을 완료하는 데 필요한 현재 활동에 대한 정보가 있을 수 있습니다. 정확한 오류 메시지를 표시하면 정확히 필요한 것을 가리킬 수 있습니다. 그러나 일반적으로 그럴 필요가 없는 한 액티비티 컨텍스트를 사용하십시오.
XXXActivity.this를 쓰면 정확한 오류 메시지를 받을 수 있고 앱의 다양한 정보에 접근할 수 있다고 한다.
이 글의 답변은 좀 길지만 자세히 읽어보니 어느 정도 이해는 됐다.
getApplicationContext() is almost always wrong. Ms. Hackborn (among others) have been very explicit that you only use getApplicationContext() when you know why you are using getApplicationContext() and only when you need to use getApplicationContext().
To be blunt, "some programmers" use getApplicationContext() (or getBaseContext(), to a lesser extent) because their Java experience is limited. They implement an inner class (e.g., an OnClickListener for a Button in an Activity) and need a Context. Rather than using MyActivity.this to get at the outer class' this, they use getApplicationContext() or getBaseContext() to get a Context object.
You only use getApplicationContext() when you know you need a Context for something that may live longer than any other likely Context you have at your disposal. Scenarios include:
-
Use getApplicationContext() if you need something tied to a Context that itself will have global scope. I use getApplicationContext(), for example, in WakefulIntentService, for the static WakeLock to be used for the service. Since that WakeLock is static, and I need a Context to get at PowerManager to create it, it is safest to use getApplicationContext().
-
Use getApplicationContext() when you bind to a Service from an Activity, if you wish to pass the ServiceConnection (i.e., the handle to the binding) between Activity instances via onRetainNonConfigurationInstance(). Android internally tracks bindings via these ServiceConnections and holds references to the Contexts that create the bindings. If you bind from the Activity, then the new Activity instance will have a reference to the ServiceConnection which has an implicit reference to the old Activity, and the old Activity cannot be garbage collected.
Some developers use custom subclasses of Application for their own global data, which they retrieve via getApplicationContext(). That's certainly possible. I prefer static data members, if for no other reason than you can only have one custom Application object. I built one app using a custom Application object and found it to be painful. Ms. Hackborn also agrees with this position.
Here are reasons why not to use getApplicationContext() wherever you go:
-
It's not a complete Context, supporting everything that Activity does. Various things you will try to do with this Context will fail, mostly related to the GUI.
-
It can create memory leaks, if the Context from getApplicationContext() holds onto something created by your calls on it that you don't clean up. With an Activity, if it holds onto something, once the Activity gets garbage collected, everything else flushes out too. The Application object remains for the lifetime of your process.
- getApplicationContext ()는 거의 항상 잘못되었습니다. Ms. Hackborn은 getApplicationContext ()를 사용하는 이유를 알고 getApplicationContext ()를 사용해야 할 때만 getApplicationContext()를 사용한다는 것을 매우 명시적으로 설명했습니다.
솔직히 말해서, "일부 프로그래머"는 Java 경험이 제한되어 있으므로 getApplicationContext() (또는 getBaseContext()를 덜 사용합니다)를 사용합니다. 내부 클래스(예 : 액티비티의 버튼에 대한 OnClickListener)를 구현하고 컨텍스트가 필요합니다. MyActivity.this를 사용하여 외부 클래스를 가져 오는 대신 getApplicationContext() 또는 getBaseContext()를 사용하여 Context 객체를 가져옵니다. 당신이 처분할 수있는 다른 어떤 Context보다 오래 살 수 있는 무언가에 대한 Context가 필요하다는 것을 알고있을 때만 getApplicationContext()를 사용합니다. 시나리오에는 다음이 포함됩니다. 자체적으로 전역 범위를 가질 Context에 연결된 무언가가 필요한 경우 getApplicationContext()를 사용하십시오.
예를 들어 WakefulIntentService에서 getApplicationContext()를 사용하여 정적 WakeLock을 서비스에 사용합니다.
WakeLock은 정적이며 PowerManager에서 생성하려면 컨텍스트가 필요하므로 getApplicationContext()를 사용하는 것이 가장 안전합니다. onRetainNonConfigurationInstance()를 통해 Activity 인스턴스 간에 ServiceConnection (즉, 바인딩에 대한 핸들)을 전달하려는 경우 Activity에서 서비스에 바인딩 할 때 getApplicationContext()를 사용합니다. Android는 이러한 ServiceConnections를 통해 내부적으로 바인딩을 추적하고 바인딩을 생성하는 컨텍스트에 대한 참조를 보유합니다. 액티비티에서 바인딩하면 새 액티비티 인스턴스는 이전 액티비티에 대한 암시적 참조가있는 ServiceConnection에 대한 참조를 갖게 되며, 이전 액티비티는 가비지 수집될 수 없습니다. 일부 개발자는 자신의 전역 데이터에 대해 Application의 사용자 지정 하위 클래스를 사용하며, 이는 getApplicationContext()를 통해 검색합니다. 그것은 확실히 가능합니다. 다른 이유없이 하나의 사용자 지정 Application 개체만 가질 수 있는 경우 정적 데이터 멤버를 선호합니다. 사용자 지정 Application 개체를 사용하여 하나의 앱을 빌드했는데 고통스러웠습니다. Hackborn씨도 이 입장에 동의합니다. 어디를 가든 getApplicationContext()를 사용하지 않는 이유는 다음과 같습니다.
- 액티비티가 수행하는 모든 것을 지원하는 완전한 컨텍스트가 아닙니다.
- 이 컨텍스트로 수행하려는 다양한 작업은 대부분 GUI와 관련된 실패합니다.
getApplicationContext()의 Context가 정리하지 않은 호출에 의해 생성된 무언가를 보유하면 메모리 누수가 발생할 수 있습니다. Activity를 사용하면 무언가를 보유하고 있으면 Activity가 가비지 수집되면 다른 모든 것도 플러시됩니다. Application 개체는 프로세스 수명 동안 유지됩니다.
요약하자면 전역 범위를 가질 컨텍스트에 연결된 뭔가가 필요하면 getApplicationContext()를 쓰는데, 보통은 2가지 이유 때문에 이걸 쓰지 않는다고 한다.
영문 자료는 봐도 무슨 소린지 이해하려면 시간이 좀 걸려서 한글 자료를 좀 찾아봤다.
먼저 안드로이드엔 2개의 Context가 있다. 위에서 계속 나온 애플리케이션 컨텍스트와 액티비티 컨텍스트가 그것이다.
애플리케이션 컨텍스트 = 앱 자체와 연동되는 것, 앱의 수명 주기가 지속되는 동안 동일한 객체다. 앱을 종료 후 다시 실행시킬 때만 바뀐다
액티비티 컨텍스트 = 액티비티와 연동된 거라 액티비티를 죽이고 다시 시작하면 액티비티 컨텍스트도 바뀐다.
두 컨텍스트 중 어떤 컨텍스트를 쓰더라도 대부분 문제없는 상황이므로 this를 써도 작동하고 getApplicationContext()를 써도 작동한다. this로 오류가 난다면 해당 액티비티가 없어서 발생하므로 getApplicationContext()를 넣으면 작동한다.
어떤 곳에선 애플리케이션 컨텍스트 사용을 권장하는데, 이유는 수명이 길고 Null 오류를 피할 수 있기 때문이다.
하지만 다이얼로그, 액티비티 시작, layout inflate 등에선 액티비티 컨텍스트를 써야 할 수 있다.
더 파고들고 싶지만 이 이상 깊게 파봤자 의미가 없을 듯해서 여기서 정리하겠다.
안드로이드에는 애플리케이션 컨텍스트, 액티비티 컨텍스트 2종류의 컨텍스트가 있다.
애플리케이션 컨텍스트는 앱 전체의 생명주기와 연결돼 있고 액티비티 컨텍스트는 액티비티의 생명주기와 연결되어 있다.
애플리케이션 컨텍스트는 앱이 종료되고 재시작되면 바뀌지만, 액티비티 컨텍스트는 onDestroy()가 실행되어 액티비티가 죽은 뒤 다시 켜지면 그 때 바뀐다.
액티비티 실행 시 둘 다 정상 작동하지만 다이얼로그, layout inflate 같이 한 액티비티에서 다뤄야 하는 작업을 할 경우엔 액티비티 컨텍스트를 쓰는 게 낫다.
액티비티 컨텍스트를 쓰면 좀 더 정확한 오류 메시지(로그?)를 얻을 수 있다. <-이 부분은 확실하지 않다
애플리케이션 컨텍스트를 쓰지 않는 이유는 액티비티가 수행하는 모든 걸 지원하는 완전한 컨텍스트가 아니고, 이 컨텍스트로 수행하려는 작업은 대부분 GUI 관련된 에러 발생으로 실패한다.
'Android' 카테고리의 다른 글
[Android] You need to use a Theme.AppCompat theme (or descendant) with this activity 에러 해결 (0) | 2020.10.01 |
---|---|
[Android] split()이란? (0) | 2020.09.24 |
[Android] android.os.FileUriExposedException: exposed beyond app through Intent.getData() 에러 해결 (0) | 2020.09.18 |
[Android] 구글 드라이브 API 사용법 (0) | 2020.07.14 |
[Android] 버튼 하나로 레이아웃 나타나게 하거나 사라지게 하는 법 (0) | 2020.07.13 |