이번 주제는 어느 정도 규모가 있는 안드로이드 애플리케이션을 제작하다 보면 필수적으로 건들게 되는 Application Class에 대해서 알아보려고 합니다. 사실 이것저것 예제를 따라 많이 사용을 했었던 Class인데, 막상 뭐냐고 물으니 대충 앱 정보를 가지기 위해 전역 변수 등의 정보를 가지고 있는 Class가 아닐까? 하는 정도의 수준에 머물러 있었습니다. 그래서 이번에 한 번 제대로 알아봐야 하지 않을까 하는 생각에 글을 끄적여 봅니다.
일단 Application Class가 언제 실행되는지 알아야 할 필요가 있습니다.
먼저 안드로이드 스튜디오를 통해 안드로이드 앱을 제작하게 되면, 개발자가 볼 필요는 없지만 안드로이드에서도 숨겨진 main 함수가 존재하고 있다는 것을 알 수 있습니다. main 함수가 실행되게 되면 먼저 메인 루퍼와 핸들러를 호출시켜 main을 실행시킨 Thread를 MainThread(UIThread)로 설정하고 MainThread의 루퍼를 실행시킵니다. 이 MainThread에서 루퍼와 메시지 큐를 연결해 MainThread로서의 역할을 다 할 수 있게 설정하고 나면 이제 첫 번째 액티비티로 설정된 액티비티의 실행을 위한 코드를 실행시킵니다. 이때 첫 번째 액티비티를 생성하기 전 단계인 handleLaunchActivity 에서 Context, Component, Application과 같은 정보를 설정하고 추가합니다.
위와 같은 코드는 보통 앱이 빌드되는 과정에서 안드로이드 스튜디오라는 프레임워크가 개발자 모르게 자동으로 실행시켜 주기 때문에 굳이 알고 싶어서 찾아보거나, 공부를 위해 찾아보지 않는 이상 알기는 어려운데요. 어쨌든 이렇게 첫 액티비티의 실행 전에 초기화되는 Class이기 때문에, UI를 생성하기 전에 필요한 데이터들을 미리 설정하거나 각 액티비티의 상태를 전역으로 관리하거나(registerActivityLifeCycleCallback을 지원) 로깅 등 애플리케이션 전역에서 사용될 수 있는 기능들에 대해 정의해두는 공간이라고 볼 수 있습니다.
공식 홈페이지에서는 아래와 같이 설명되어 있습니다.
전역 응용 프로그램 상태를 유지하기 위한 기본 클래스입니다. 하위 클래스를 만들고 이 하위 클래스의 정규화된 이름을 "android:name"AndroidManifest.xml <application>태그의 속성으로 지정하여 고유한 구현을 제공할 수 있습니다. Application 클래스 또는 Application 클래스의 하위 클래스는 애플리케이션/패키지에 대한 프로세스가 생성될 때 다른 클래스보다 먼저 인스턴스화됩니다.
class App : Application() {
override fun onCreate() {
super.onCreate()
//여기에 코드 작성
}
}
코틀린에서는 위와 같이 Application class를 선언할 수 있습니다. 이 클래스는 Manifest에 등록되어야만 사용할 수 있는데요. 아래와 같이 android:name=".(applicationClassName)"으로 application 안에 제공해주면 인식됩니다.
<application
android:name=".App"
</application>
이렇게 인식한 Application Class는 onCreate, onTerminate, onLowMemory, registerActivityLifecycleCallbacks 등 여러가지 메소드를 오버라이드 할 수 있습니다. 자세한 내용들은 아래 링크를 이용해 android developer의 메소드를 확인하시고 사용하면 되겠습니다.
https://developer.android.com/reference/android/app/Application
이 클래스는 주로 액티비티의 전환을 액티비티 밖에서 제어하거나, 전역변수로 두는 것이 더 효율적인 (이는 애플리케이션의 종류에 따라 달라지겠지만)변수 및 메소드, 또는 애플리케이션 시작 전에 필수적으로 불러와야 하거나 저장해야하는 것들에 대해 사용하면 매우 효율적으로 사용할 수 있습니다. 하지만, 이 클래스 내에서 선언되는 것들은 기본적으로 메모리 상에서 계속 올라가 있기 때문에 많은 용량을 차지하는 데이터를 지니거나 굳이 들고 있을 필요가 없는 것들을 가지고 있는 것에 대한 고민이 항상 필요합니다.
이 클래스를 처음 접했을 때는 로깅을 위함이었는데, 딱히 이 클래스가 어떤 상태인지 알 필요가 없어 크게 고민하면서 작성했던 기억이 별로 없네요. 하지만 이번에 어떤 UI가 동작하고 있는지 확인하지 않고(항상 이미 알고 있는 상태로), context를 다루고 싶어져서 방법을 찾다보니 이 클래스에 대해 관심이 많아졌습니다. 아무래도 메모리 문제를 해결하기 위해서는 어떤 방식으로 메모리에 데이터가 올라가고 내려가는지를 확실히 알고 있어야 하기 때문에 코드를 작성하기가 점점 더 조심스러워 지고 있습니다.
아직 모르는 게 더 많아 꾸준히 공부중이지만(으레 모든 프레임워크가 그렇듯), 알면 알 수록 알아야 할 게 늘어나는 프레임워크가 아닌가 싶습니다(울고 싶네요).
'안드로이드 > 기타' 카테고리의 다른 글
viewLifecycleOwner.lifecycleScope vs lifecycleScope (0) | 2022.10.20 |
---|---|
안드로이드 쓰레드의 통신 과정(Looper, Handler, MessageQueue) (0) | 2022.09.25 |
ANR(Application Not Responding)이란? (0) | 2022.08.06 |
LiveData vs RxJava (0) | 2022.07.08 |
AAC 데이터 바인딩이란? (0) | 2022.05.25 |
댓글