Android Activity Lifecycle 2

안드로이드 Activity Lifecycle 2를 알아보겠습니다.


Activity Lifecycle 글은 아래에 있습니다.




Activity의 Lifecycle에 대한 문서는 아래에 있습니다.




onCreate()

시스템이 activity를 생성할 때, 실행됩니다. activity에 필요한 필수 요소들을 초기화해야 합니다. 예로 들면 뷰를 생성하거나 데이터를 리스트에 연결하는 등의 행위 등이 있습니다. 

가장 중요한 것은 activity의 유저 인터페이스를 정의하기 위해 setContentView를 반드시 실행해야 합니다.


전체 lifecycle 중에서 한 번만 실행됩니다. 리스트에 data를 bind 하거나 viewModel에 연결하거나, class-scope 변수들을 초기화합니다. onCreate()에서는 savedInstanceState 변수를 Bundle로 받습니다. activity가 이전에 존재하지 않았다면, savedInstanceState는 null 값을 가집니다. 



onStart()

onCreate()가 완료된 다음에 실행됩니다. Activity가 Started 상태에 들어가게 되고 비로소 사용자의 눈에 보이게 됩니다. onStart()에서는 activity가 foreground로 가서 상호작용이 가능하게 되기 전에 마지막 준비해야 할 것들을 정의해 줘야 합니다.


UI를 유지하는 코드를 초기화합니다.



onResume()

사용자와 상호작용하기 직전에 호출됩니다. 이 시점에는 activity stack의 최상위에 현재 activity가 위치하게 되고, 모든 사용자의 입력을 감지하게 됩니다. 대부분의 핵심 기능들은 onResume()에 구현됩니다.


앱이 focus를 벗어나기 전까지 계속 여기에 머뭅니다. focus를 벗어나는 경우는 전화가 울리거나, 다른 activity로 가거나, 화면을 끄는 경우가 있습니다.


여기에는 foreground 상태에서 보여줘야 하는 기능들을 넣습니다. 예를 들면 카메라 뷰가 있습니다.


Paused에서 Resumed로 상태가 변화되면, onResume() 다시 실행됩니다. 따라서, onPause() 동안 release를 해야 합니다.


만약 사용자가 Multi-window를 사용한다면, 화면이 보이는 상태에서도 Paused 상태가 될 수 있습니다.


ON_START에서 초기화를 했다면, ON_STOP에서 해제합니다. ON_RESUME에서 초기화를 한다면, ON_PAUSE에서 해제합니다.




onPause()

activity가 focus를 잃고 Paused 상태에 들어가면 실행됩니다. Paused 상태는 사용자가 뒤로 가기나 최근 앱 버튼을 누르는 등의 동작으로 발생됩니다. onPause()가 실행된다는 말은 activity가 여전히 사용자에게 보이지만, 곧 activity를 떠나거나 activity가 Stopped 또는 Resumed 상태가 된다는 것을 의미합니다.


Paused 상태에 있는 activity는 사용자를 위해서 UI를 업데이트할 수 있습니다. 예를 들어 내비게이션 지도 또는 음악 플레이어라고 한다면, activity가 focus를 잃었어도 계속 UI가 업데이트된다고 사용자는 예상합니다.


onPuase()에서는 application 또는 사용자 data를 저장, 네트워크 호출, database의 transactions을 해서는 안 됩니다. 


onPaused()가 실행이 완료되면, 다음으로는 onStop() 또는 onResume()이 실행되는데, 이는 activity가 Paused 상태에 들어선 다음 어떠한 일이 일어나는지에 따라 결정됩니다.


onPause()는 항상 activity가 destroy 된다는 의미가 아닙니다. 단지 foreground에 없다는 뜻입니다. 하지만, multi-window라면 여전히 보일 수 있습니다. 


dialog처럼 새로운 반투명 activity가 열리는 경우 activity가 부분적으로 보이지만, focus 되지 않았기 때문에 paused 상태입니다.


카메라 뷰 정지와 같이 foreground에서만 필요한 부분들을 멈추는 용도로 사용될 수 있습니다.


사용자가 필요하지 않다면, 센서나 GPS 같은 리소스들을 해제하는 데에 사용할 수 있습니다.

하지만, 위에서 설명한 것과 같이 multi-window의 경우, 사용자에게 보일 수 있으므로 onStop에서 완전히 해제하는 것도 생각해 볼 수 있습니다.


onPause()는 아주 짧은 시간만 실행되기 때문에 저장 등의 행위에 적합하지 않습니다. 실행 시간이 길어서 onPause()가 종료되어도 실행되는 코드는 사용하지 않아야 합니다.


onPause()가 완료된다는 말은 activity가 Paused 상태를 벗어난다는 뜻이 아닙니다. activity가 resume 상태가 되거나 완전히 사용자에게 안 보이기 전까지 유지됩니다. 만약 activity가 resume 되면, onResume()이 다시 한번 불러와집니다.


onPause()에서 onResume()으로 넘어가면 메모리상에 있던 activity를 다시 불러오기 때문에 다른 장치들을 다시 초기화할 필요가 없습니다. activity가 완전히 보이지 않게 되면, onStop()이 호출됩니다.



onStop()

onStop()은 사용자에게 더 이상 보이지 않을 때 호출됩니다. 이러한 일은 activity가 destroyed 되거나 새로운 activity가 실행되거나 또는 존재하는 activity가 Resumed 상태에 들어가면서 기존에 Stopped된 activity를 치워낼 때 발생합니다. 

다음 콜백은 onRestart()가 되거나 onDestory()가 됩니다. onRestart()는 activity가 다시 사용자와 상호작용 가능한 상태로 돌아갈 때 불러와지고, onDestory()는 activity가 완전히 종료될 때 불러와집니다.


activity가 Stopped 상태가 되면, 보이지 않는 상태에서 불필요한 요소들을 해제해 주면 됩니다. 예를 들면 애니메이션을 멈추거나, 위치 업데이트 등이 있습니다. onPause() 대신에 onStop()에서 해제한다는 의미는 ulti-window에서 UI 관련된 작업을 계속한다는 뜻입니다.


onStop()에는 CPU 사용량이 많은 종료 작업등을 사용할 수 있습니다. 예를 들면, 데이터베이스에 정보를 저장할 마땅한 시점을 찾지 못한다면, onStop()에서 할 수 있습니다.


activity가 Stopped 상태에 들어가면, Activity 오브젝트는 모든 상태와 멤버 정보를 가지고 메모리에 보관됩니다. 하지만, window manager에는 등록되어 있지 않습니다. activity가 resume 되면, 이러한 정보들을 다시 불러옵니다.


다시 불러올 때, Resumed 상태까지의 컴포넌트들을 다시 초기화할 필요는 없습니다. 또한, 시스템이 layout 안의 View 오브젝트들의 현재 상태를 추적하고 있습니다. 따라서 사용자가 EditText에 적은 내용은 계속 유지되고 있습니다.


Stopped 상태 다음에는 유저와 상호작용하거나 완전히 종료되는 상황이 존재합니다. activity가 다시 돌아온다면, onRestart()가 실행되고, 종료된다면, onDestory()가 실행됩니다.



onRestart()

activity가 Stopped 상태에서 restart 될 때 시스템에서 실행합니다. activity가 정지된 시점의 상태를 복구합니다.


onRestart() 다음에는 항상 onStart()가 실행됩니다.



onDestory()

activity가 destroyed 되기 전에 불러와집니다. activity가 받는 마지막 콜백입니다. onDestroy()는 보통 activity의 리소스(activity나 프로세스가 포함한 것들 따위)를 해제할 때 사용합니다.


onDestory()가 호출되는 경우는 두 가지입니다.

1. activity를 사용자가 없애거나 finish()가 호출된 경우.

2. 화면이 회전되거나 multi-window 모드에 들어가는 등의 설정이 임시적으로 변경되는 경우.


ON_DESTROY에서는 Activity가 destoryed 되기 전 제거해야 할 것들 없앨 수 있습니다.

activity가 어떤 이유로 destroy 되는지를 구분하기 위해 로직을 넣기보다는 ViewModel을 사용합니다. ViewModel은 설정 변경 시에도 그대로 유지되어 새로 생성된 Activity에 값을 전해 줄 수 있습니다.


만약 Activity가 새로 생성되지 않는다면, ViewModel은 onCleared()가 실행되고 여기서 필요하다면 destoryed 되기 전에 모든 데이터를 제거할 수 있습니다. ViewModel 대신 isFinishing()을 사용해서 두 가지 시나리오를 구분할 수 있습니다.


만약 activity가 끝나면, onDestory()가 마지막으로 실행됩니다. onDestory()가 설정 변경으로 호출된다면, 곧바로 변경된 설정이 적용된 새로운 activity가 생성되면서 onCreate()가 실행됩니다.


onDestory()는 onStop()에서 해제되지 않은 나머지 모든 리소스를 해제합니다.




끝.



카테고리: Android​

댓글

이 블로그의 인기 게시물

Python OpenCV 빈 화면 만들기

Python urllib.parse.quote()

Python bytes.fromhex()

Android AVD Ram size change

Forensics .pyc 파일 .py로 복구하기

Android Minimum touch target size

KiCad 시작하기 7 (FreeRoute 사용하기 2)

Android Notification with Full Screen

C++ OpenCV 모폴로지 침식, 팽창

KiCad 시작하기 2 (PCB 만들기)