Bibbidi Bobbidi Boo
article thumbnail

Android를 처음 개발하면 접하게 되는 Activity, 그리고 fragment!

기본 중 기본이며, ✨면접 필수 질문✨으로 매우 매우 중요하다!!

 

Activity

Activity란?

Acitivty는 Android 4대 컴포넌트 중 하나로, 사용자와 상호작용을 담당하는 컴포넌트다.

사용자에게 UI를 제공하며, Acitivty 끼리 화면 전환이 이루어질 수 있다.

* Android 4대 컴포넌트에 대해서 나중에 포스팅하기

 

Activity의 lifecycle

개발자는 Activity의 lifecycle-callback에 따라 적합한 작업을 수행해야 한다.

Activity가 생성되거나 파괴, 혹은 다시 나갔다 들어오는 등 상태(States)가 변하면 콜백을 호출하게 된다.

출처 : https://developer.android.com/topic/libraries/architecture/lifecycle?hl=ko#lc
출처 : https://developer.android.com/guide/components/activities/activity-lifecycle#alc

순서대로 onCreate(), onStart(), onResume(), onPause(), onStop(), onDestory()을 호출한다.

각각 언제 호출되는지도 물론 중요하지만, 해당 callback에서 어떤 작업을 주로 하는지도 중요하다.

 

* 이해하기 위해 알아야 하는 개념 : App process, foreground, backgroud

*  App process

App process는 앱이 실행되기 위해 시스템이 할당한 메모리 공간과 리소스 그룹을 말한다.

Android는 메모리 부족 상황에서 우선 순위에 따라 앱 프로세스를 종료시키게 된다.

* foreground

앱이 사용자에게 보이면서, 상호작용도 가능한 상태를 말한다.

Android에서는 메모리 부족 상황에서 foreground 상태인 앱의 우선순위를 높게 처리한다.

* background

앱이 사용자에게 보이지도 않고, 상호작용도 하지 않지만, 백그라운드에서 실행 중인 상태를 말한다.

Android에서는 메모리 부족 상황에서 background 상태인 앱의 우선순위를 낮게 처리한다.

 

onCreate()

onCreate()는 ActivIty가 처음 생성될 때 호출된다. 

이 때 Activity에서는 필요한 컴포넌트를 초기화하는 작업이 필요하다.

대표적인 예시가 setContextView()

해당 메소드를 사용하여 Activity의 레이아웃을 설정한다.

 

그 외에도 다음과 같은 작업을 해당 메소드에서 수행할 수 있다.

  • View 객체 초기화 : findViewById()를 사용해 View 객체 초기화하기
  • 데이터 초기화 : 데이터베이스 연결, 파일 로드, 네트워크 연결 등 Acitivity에서 필요한 데이터 초기화
  • 리소스 초기화 : Activity에서 사용할 리소스 초기화
  • ActionBar 설정 : supportActionBar를 설정하고, 필요한 메뉴를 추가한다.
  • 상태 저장 : saveInstanceState를 사용해 저장된 이전 상태를 복원할 수 있다. 즉, 화면 회전 등이 이루어지고 난 후 Activity가 다시 생성됐을 때 이전 상태를 복원할 수 있다.

 

Android는 메모리 부족 상황에서 우선 순위에 따라 앱 프로세스를 종료시키게 된다.(Apps with higher priority need memory)

onStop() 이후 해당 상황이 발생하여 앱 프로세스가 종료된 후(App process killed), 다시 실행하게 될 때(User navigates to the activity)에는 onCreate()부터 다시 시작하게 된다. 

 

onStart()

onStart()는 Acitivty가 화면에 보여지기 시작할 때 호출된다.

이 때는 Activity가 foreground로 이동하기 전에 필요한 작업을 해야 한다.

 

대표적인 예시로 애니메이션 작업.

Activity가 화면에 보여질 때 자연스럽게 전환 효과를 보여줄 수 있다.

 

그 외에도 센서나 위치 정보 초기화하고 등록하거나, UI를 업데이트하는 작업이 이루어질 수 있다.

 

* Q. 왜 센서나 위치 정보 등을 초기화하고 등록하는 작업이 onStart()에서 이루어져야 할까?

해당 작업은 onCreate()에서도 물론 이루어질 수 있다.

그러나 onCreate()는 Activity에서 필요한 컴포넌트를 초기화하기 위한 작업을 해야한다.

onCreate()가 호출되는 시점, 즉 Activity가 생성되는 시점에 하드웨어 자원을 초기화하고 등록하는 작업을 수행하는 경우 문제는 시간이 매우 오래 걸릴 수 있다.

Activity가 생성될 때 시간이 너무 오래 걸리면 사용자 경험에 안 좋은 영향을 미친다.

앱이 빠르게 실행되어야 하는데 그렇지 못하다는 것.

onStart()에서 이루어지면 Activity가 화면에 표시되는 동안 하드웨어 자원 초기화 및 등록 작업이 끝나기 때문에 조금 더 빠르고 안정적으로 동작하게 된다.

 

Activity가 생성될 때 호출되는 onCreate()와 비교하면, onStart()가 많이 호출된다.

이는 onStart()가 Acitivty가 보이는 화면으로 전환될 때마다 호출되기 때문이다.(User navigates to the activity)

예를 들어 다른 Acitivty에서 현재 Activity를 호출하거나, 현재 Activity가 background에 있다가 foreground로 전환될 때 등의 상황에서 호출될 수 있다.

 

onResume()

onResume()은 Activity가 사용자와 상호작용을 시작하기 직전에 호출된다. 

이 때 Activity는 사용자에게 완전히 보이며 포커스를 받고, running 상태가 된다.

 

* 포커스를 받는다?

예를 들면 Android에서 제공하는 Multi-Window 상태에서 두 개의 앱을 실행해 두 개의 화면이 보인다고 가정하자.

이 때 사용자가 앱 하나를 터치하면 해당 앱은 포커스를 받은 상태이다.

반대로, 다른 앱도 화면에 여전히 보이고 있지만 포커스를 잃은 상태이다.

즉 상호작용이 가능하면 포커스를 받은 것이다.

 

onResume()은 Activity가 포커스를 다시 받았을 때(Resume, 재개) 필요한 작업을 수행하기 적합하다.

예를 들어 포커스를 잃었을 때 애니메이션이 중지되었거나, 카메라 리소스가 해제되었거나, 비디오 재생이나 음악 재생처럼 백그라운드에 있을 때 중지된 작업이 있다면 다시 시작하거나 재할당하는 작업을 수행할 수 있다.

 

onResume()은 다른 Activity가 foreground에 오고 난 후, 다시 해당 Activity로 돌아올 때(User returns to the activity) 호출되므로 onStart()에 비해 자주 호출된다.

 

onPause()

onPause()는 onResume()에 대응되는 메소드로, Activity가 포커스를 잃었을 때 호출(Another activity comes into the foreground)된다.

* Activity가 포커스를 잃었을 때는 다른 Activity로 이동할 때도 있지만, Dialog가 열렀거나 Multi-Window 상태에서 보이지 않을 때도 해당한다.

 

Activity가 일시 중지(일시 중지, Pause)되기 전 상태를 저장하고, 자원을 해제하는 등 작업을 수행하기 적합하다.

위의 onResume()에서 들었던 예시처럼 애니메이션 효과를 중지하거나, 실행 중인 작업을 중단하고자 할 때 해당 메소드에서 수행할 수 있다.

이런 작업을 수행하면 일시 중지 상태가 되는 과정에서 불필요한 자원 소비가 줄고, 앱 성능 또한 향상될 수 있다.

 

반면, Android 공식 문서에는 onPause()에서 애플리케이션 또는 사용자 데이터를 저장하거나, 네트워크를 호출하거나, 데이터베이스 트랜잭션을 실행해선 안 된다고 한다.

이는 onPause()가 아주 잠깐 실행되기 때문에 저장 작업을 실행하기에 시간이 부족하기 때문이다.

onPause()가 다 실행되고 난 후에도 작업을 완료하지 못할 수도 있으므로 해당 작업처럼 시간이 오래 걸린다면 onPause() 대신 onStop() 상태일 때 실행하는 것이 좋다.

 

onStop()

onStop()은 onStart()에 대응되는 메소드로, Activity가 더 이상 화면에 보이지 않을 때(The activity is no longer visible) 호출된다.

 

Activity가 중지(중지, Stop)되었을 때, 즉 보이지 않을 때 실행할 필요가 없는 기능을 모두 정지할 수 있다.

이 때는 필요없는 자원을 해제하거나 조정하는 등의 작업을 수행하기 적합하다.

예를 들면 애니메이션을 중지하거나, 위치를 업데이트하는 작업을 수행할 수 있다.

 

혹은 onPause()에서 CPU를 많이 소모해 하지 못한 종료 작업(ex. DB 저장)을 onStop()에서 수행할 수 있다.

 

onDestory()

onDestroy()는 onCreate()와 대응되는 메소드로, Acitivty가 파괴되기 전에 호출된다.

Activity가 파괴되는 경우는 Activity가 finish() 등을 호출 등으로 Activity가 종료되는 경우, 혹은 화면을 회전하거나 Multi-Window 모드로 Configuration이 변경되어 system이 일시적으로 Activity를 소멸하는 경우(The activity is finishing or being destroyed by the system)에 해당한다.

 

* Configuration이 변경되는 경우 예시

  • 기기 회전
  • Multi-Window 모드
  • 시스템 테마 변경(ex. 다크 모드)
  • 글꼴 크기 및 두께 변경
  • 언어 변경
  • 하드웨어 키보드 연결 혹은 연결 해제

 

이 때는 Activity가 종료되기 전에 필요한 작업(ex. 리소스 해제)을 수행하지만, 대부분 onStop()에서 정리를 한다(...).

그래도 ViewModel의 onCleared() 메서드는 onDestory()에서 호출해야 한다.

 

* viewModel의 onCleared()?

viewModel은 Android와 Fragment 등 Android 컴포넌트와 다르게 화면 회전 등 Configuration 변경이 일어나도 파괴되지 않는다.

때문에 Configuration 변경이 일어나도 데이터를 유지할 수 있다.

그러나 만약 Activity가 파괴된 이후에 다시 재생성되지 않는다면, ViewModel은 메모리에 계속 남아있어 메모리 누수(memory leak)가 발생할 수 있다.

그러므로 ViewModel의 onCleared() 메서드를 호출하여 ViewModel에서 관리하는 리소스를 해제하도록 해야한다.

 

요약

  • Activity란?
    • 사용자와 상호작용하기 위한 컴포넌트로, UI를 제공한다.
  • Activity의 lifecycle
    • Activity의 상태 변경에 따라 lifecycle callback이 호출된다. 개발자는 각 callback에 적합한 작업을 수행해야 한다.
    • onCreate() - onDestory()
      • onCreate()는 Activity가 처음 생성될 때 호출되며, Activity가 필요한 컴포넌트를 초기화하는 작업을 수행하기 적합하다. 예시로, setContextView() 메서드를 호출해 레이아웃을 설정하는 작업이 있다.
      • onDestory()는 Activity가 파괴될 때 호출되며, onStop()에서 하지 못한, Activity가 종료되기 전 필요한 작업을 수행하기 적합하다. 예시로, ViewModel의 onCleared()를 호출해 ViewModel에서 관리하는 리소스를 해제하는 작업 등이 있다.
    • onStart() - onStop()
      • onStart()는 Activity가 화면에 보여지기 시작할 때 호출되며, Activity가 foreground 상태가 되기 전 필요한 작업을 수행하기 적합하다. 예시로, 애니메이션 효과나 센서와 위치 정보를 초기화 하는 작업이 있다.
      • onStop()은 Activity가 화면에 보이지 않게 되었을 때 호출되며, 이 때 보이지 않을 때 할 필요가 없거나 혹은 부하가 커서 onPause()에서 할 수 없는 작업을 종료하기 적합하다. 예시로, 애니메이션 효과를 정지하거나, DB에 저장하는 작업 등이 있다.
    • onResume() - onPause()
      • onResume()은 Activity가 사용자와 상호작용을 시작하기 직전에 호출되며, Activity가 focus를 받게 되어 재개하는 상황에 필요한 작업을 수행하기 적합하다. 예시로 멈춘 애니메이션이나 동영상, 음악 등을 다시 재생시키는 것이 해당될 수 있다.
      • onPause()는 Activity가 focus를 잃었을 때 호출되며, Activity가 일시중지되기 전 필요한 작업을 수행하기 적합하다. 예시로, 애니메이션을 정지하거나 동영상이나 음악 등을 다시 재생시키는 게 해당될 수 있다.

 

참조

https://developer.android.com/guide/components/activities/intro-activities?hl=ko 

 

활동 소개  |  Android 개발자  |  Android Developers

활동은 사용자가 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기와 같은 작업을 하기 위해 상호작용할 수 있는 화면을 제공하는 애플리케이션 구성요소입니다. 각 활동에는 사용자 인터페

developer.android.com

 

https://developer.android.com/guide/components/activities/activity-lifecycle?hl=ko 

 

활동 수명 주기에 관한 이해  |  Android 개발자  |  Android Developers

활동은 사용자가 전화 걸기, 사진 찍기, 이메일 보내기 또는 지도 보기와 같은 작업을 하기 위해 상호작용할 수 있는 화면을 제공하는 애플리케이션 구성요소입니다. 각 활동에는 사용자 인터페

developer.android.com

https://developer.android.com/topic/libraries/architecture/lifecycle?hl=ko#lc 

 

수명 주기 인식 구성요소로 수명 주기 처리  |  Android 개발자  |  Android Developers

새 Lifecycle 클래스를 사용하여 활동 및 프래그먼트 수명 주기를 관리합니다.

developer.android.com

 

 

 

쓰다보니 글이 길어져서... 나눠서 업로드 할 예정

profile

Bibbidi Bobbidi Boo

@비비디

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!