-
안드로이드 Context안드로이드 학습/Android 기술면접 대비 2024. 8. 22. 17:54
차례: 1) Context란? 2) Context와 하위클래스 3) Application & Activity Context 4) Context가 필요한 이유:
앱 개발을 하면서 context를 자주 봤었다. 보기만 했었고 왜 있는건지나 정확히 어떻게 사용되는 것인지에 대해 깊게 생각해보지는 않았던 것 같다. 그래서 이참에 한번 제대로 학습해보기로 결정했다.
1. Context란?
우선, developer 사이트의 context 설명을 보자.
애플리케이션 환경에 대한 전역 정보에 대한 인터페이스입니다. 이는 Android system에 의해 구현된 추상 클래스입니다. 이를 통해 애플리케이션별 리소스 및 클래스에 액세스할 수 있으며, 액티비티 시작, 인텐트 방송 및 수신과 같은 애플리케이션 수준의 작업에 대한 업콜을 제공합니다.
링크 : https://developer.android.com/reference/android/content/Context/전역 정보에 대한 인터페이스, 추상 클래스라는데 이 내용은 그렇다고 생각하면 될 것 같고,
사용되는 곳은 application의 resource 및 class에 접근이나 Activity 시작, Intent 수신, Broadcasting 등에 사용된다는 것 같다.
Context가 다양하게 사용되는 것 같았는데 이렇게 짧은 설명으로는 전반적인 사용되는 것에 대한 이해가 부족해서 좀 더 학습이 필요 할 것 같다.
여러 내용들을 더 찾아보고 정리해 보면 아래와 같다.
- Application의 현재 상태를 나타낸다.
- Activity와 Application의 정보를 얻기 위해 사용할 수 있습니다.
- Activity, Application 클래스는 Context클래스를 상속받은 클래스. Context는 여러 컴포넌트의 상위 클래스이다.
- Resource(strings, themes, assets 등) 나 Database, Shared preference 에 접근 할 수 있게 해준다.
- 시스템 서비스 접근이나 패키지 이름, LayoutInflater 등등 데 사용된다.
코드 예시 :
더보기1. 리소스 접근
String appName = context.getResources().getString(R.string.app_name);
2. 서비스 접근
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.some_layout, null);
3. 액티비티 또는 애플리케이션 실행
Intent intent = new Intent(context, AnotherActivity.class); context.startActivity(intent);
4. 리소스 및 애플리케이션 레벨 정보 획득
// 애플리케이션의 패키지 이름 가져오기 String packageName = context.getPackageName(); // 애플리케이션의 버전 정보 가져오기 PackageManager pm = context.getPackageManager(); PackageInfo info = pm.getPackageInfo(packageName, 0); String versionName = info.versionName;
5. LayoutInflater 사용 예시
LayoutInflater inflater = LayoutInflater.from(context); View view = inflater.inflate(R.layout.some_layout, null);
위에 Activity, Application 클래스는 Context클래스를 상속받은 클래스고 Context는 여러 컴포넌트의 상위 클래스라는 설명이 있는데 Context의 구조를 좀 보고 넘어가자.
2. Context와 하위클래스
Application, Activity, Service의 상속을 따라가다 보면 Context가 나온다.
Context는 추상 클래스이고 ContextWrapper는 Context를 직접 상속한 클래스로 이름처럼 Context를 래핑하여 Context와 관련된 호출을 모두 담당하여 처리하게 됩니다. ContextImpl 추상클래스인 Context를 실제 구현한 클래스로 앱에서 직접 사용할 수 있는 클래스는 아니지만, 소스코드는 공개되어 있어서 확인할 수 있습니다.
Context는 안드로이드 개발 중 다양한 곳에서 사용되기 때문에 정확하게 어떻게 사용하는지 이해 하는 것이 중요하다. Context를 잘못 사용한다면 memory leak이 발생하기 때문이다. Memory Leak을 방지하며 사용하기 위해서 주로 사용되는 2가지 타입의 Context (Application context, Activity Context)를 필요할때 잘 사용해야 한다.
3. Application & Activity Context
Application Context와 Activity Context에 관련된 내용은 아래 블로그 내용을 참고하였다. 링크 : https://outcomeschool.com/blog/context-in-android-application
Context 는, 크게 나누자면 또 두 가지로 나눌 수 있다.
- Application Context
- Activity Context
Application Context :
- Application Context는 싱글톤 인스턴스이며 Activity에서 (Kotlin) applicationContext, (Java) getApplicationContext() 를 통해 얻을 수 있는 싱글톤 인스턴스이다.
- Application Context는 application lifecycle과 연결되어 있다. 현재의 컨텍스트와 분리된 라이프사이클을 가진 컨텍스트가 필요할 때나 액티비티의 범위를 넘어서 컨텍스트를 전달할 떄에 사용합니다. (현재의 컨택스트는 아마도 activity context를 의미하는 것으로 보인다.)
예제 1 : 만약 당신의 application에서 싱글턴 객체를 생성하였는데 그 객체에 컨텍스트가 필요하다면, 애플리케이션 컨텍스트를 사용하면 됩니다.
(Activity Context를 사용한다면, 싱글톤 객체는 한번 생성되면 계속 메모리에 남아있지만 Activity Context는 Activity 종료시 회수되어야 함으로 메모리 누수가 발생할 수 있다.
예제 2: Toast 메시지를 보여줄때 사용.
(Toast Message 같은 경우 Activity가 종료되어도 여전히 메시지를 보여주는 것을 볼 수 있다. 그래서 Activity Context가 아닌 Application Context가 권장된다.)
메모리 릭이란???
더보기- 어플리케이션은 동작을 위해 메모리가 필요합니다. 어플리케이션이 사용이 끝난 메모리를 반환하지 않는 것을 메모리 릭이라고 합니다. 보통 릭이 발생하면, 사용한 메모리는 반환하지 않은 채 추가로 필요한 메모리를 시스템에 요청하기 때문에 사용하는 메모리 양이 계속 증가합니다.
- 이 과정이 계속되면, (1) 버벅거림 (2) OOM(Out Of Memory)를 발생시키고 어플리케이션이 강제 종료후 App에 할당되었던 메모리가 회수
GC (Garbage Collected) 이란 ???
더보기- GC는 더이상 사용되지 않는 쓰레기 객체들을 정리하는 작업을 한다.
- GC는 필요에 따라 자동으로 실행된다.
Activity Context :
- Activity Context 는 액티비티 안에서만 사용 가능하다. 특정 Activity 의 라이프 사이클에 종속되어 있다.
- Activity 내에서 사용될 때 넘겨주거나, Activity의 life cycle이 같은 객체를 생성할 때 넘겨준다. 즉, Activity 가 소멸되면 해당 Context 도 같이 소멸되는 것이다.
- Activity Context 같은 경우 xml 파일을 inflate 할때, 리소스를 접근할 때, Activity 전환 등 다양한 곳에 활용된다.
Application 그림 위에 그림을 보면 안드로이드 Application내에 Application Context는 오직 한개만 있다. 한번 메모리에 할당 되면 application의 라이프사이클에 종속되고, MainActivity1, MainActivity2, 다른 Activity 등에서 다 사용 가능하다.
반면에 Activity1 Context, Activity2 Context는 각각의 MainActivity1, MainActivity2에서만 활용된다.
Application Context 를 사용하면 안되는 경우
- Application Context를 사용하면 안 되는 경우는 액티비티의 UI와 밀접하게 관련된 작업이나 특정 액티비티의 생명 주기와 연관된 작업입니다
- 예를 들어 AlertDialog에 Application Context를 넣으면 에러가 발생한다. Dialog는 화면에 표시되는 UI 요소이기 때문에, 이를 표시하려면 현재 활성화된 액티비티의 컨텍스트가 필요한데, Activity Context는 현재 액티비티의 UI 상태와 테마 정보를 포함하지만, Application Context는 이런 정보가 없다.
4. Context가 필요한 이유:
앞서 Context는 전역적인 어플리케이션 정보에 접근하거나 어플리케이션 연관된 시스템 기능을 수행하기 위해 사용한다고 했다. 나는 안드로이드 개발부터 시작하고 개발자 경력이 다 안드로이드 개발자이기 때문에 이상하게 생각하지 않았지만 다른 블로그들을 참고하다보니 이것은 다른 플랫폼과는 다른 방식이라고 되어있었다.
예를 들어, C#에서 실행파일 이름을 가져오는 방법은 아래와 같다.
System.AppDomain.CurrentDomain.FriendlyName
Activity에서는 아래와 같다.
fun getAppName(context: Context): String { var appName = "" try { val pm = context.packageManager val i = pm.getPackageInfo(context.packageName, 0) appName = i.applicationInfo.loadLabel(pm).toString() + "" } catch (e: PackageManager.NameNotFoundException) { } return appName }
C# 혹은 다른 OS application은 대부분 System에서 제공하는 함수를 호출해서 시스템 기능을 수행할 수 있지만 안드로이드에서는 Context에 정의된 함수를 호출해야 된다.
일반적으로 OS의 주된 업무는 process를 관리하는 것이다. 그래서 특정 process와 어플리케이션에 매핑되어 실행되고 있다면 System이 직접 process 정보에 대해 물어 볼 수 있을 것이다.
하지만 안드로이드 같은 경우 일반적인 application과 프로세스가 서로 독립적으로 존재한다. 예를 들자면, 안드로이드 플랫폼에서 프로세스가 없는 상황에도 Service나 Broadcast Receiver가 어플리케이션 실행 여부와 무관하게 백그라운드에서 실행 가능합니다.
안드로이드에서도 프로세스는 OS 커널에서 관리된다. 하지만 application 정보는 ActivityManagerService에서 관리한다. 특정 토큰을 키 값으로 'key-valule' 쌍으로 이루어진 배열을 이용하여 현재 작동중인 어플리케이션 정보를 관리한다.
Context는 application과 관련되 정보에 접근하려 할때 application과 연관된 시스템 레벨의 함수를 호출하고자 할 때 사용된다. 안드로이드에서 application이 하나가 아니기 때문에 정보를 얻고자 하는 어플리케이션이 어떤 어플리케이션인지에 관한 키 값도 필요하다.
안드로이드 플랫폼상에서의 관점에서 살펴보면, Context는 두가지 역할을 수행하기 때문에 필요하다.
- 자신이 어떤 어플리케이션을 나타내고 있는지 알려주는 ID 역할
- ActivityManagerService 에 접근할 수 있도록 하는 통로 역할
정리 :
- 안드로이드는 process가 종료 되어도 application 정보가 필요하다.
- 그래서 다른 OS와 다르게 System이 아닌 ActivityManagerService가 application 정보 보유.
- 그걸 접근하는게 Context.
- 궁극적으로 Context를 통해서 시스템 레벨 함수나, application 정보를 가져올 수 있다.
'안드로이드 학습 > Android 기술면접 대비' 카테고리의 다른 글
안드로이드 비동기 처리 2-3 (Operators : 연산자들) (0) 2024.08.29 안드로이드 비동기 처리 2-2 (RxJava 버전 및 5가지 Base classes) (0) 2024.08.29 Handler와 Looper (0) 2024.08.20 Serializable, Parcelable (Intent) 그리고 Parcelize (0) 2024.08.08 안드로이드 비동기 처리 2-1 (RxJava & RxAndroid) (0) 2024.08.08