1. Android System 은 LifeCycle(생명주기) 의 특정단계에 해당하는 특정한 콜백 메소드를 호출하여 Activity Instance 의 코드를 시작합니다.
- Activity Class 에는 Main 이 없다.
- Activity Class 에는 LifeCycle 에 해당하는 콜백 메소드가 존재한다.
- Activity Instance 에서 콜백 메소드는 Android System 이 호출한다.
2. Activity는 앱이 UI를 그리는 window를 제공합니다. 이 window는 일반적으로 Screen을 채우지만 (Full-Screen) Screen보다 작고 다른 window 위에 떠 있을 수 있습니다. 일반적으로 하나의 Activity 는 앱에서 하나의 Screen을 구현합니다.
- Activity 는 UI가 있는 App Component(앱 구성요소) 이다.
- Activity 는 window을 가득 채울수도 있고, 그보다 작은 상태로 window위에 있을 수 있다.
- 일반적으로는 Activity 는 앱에서 하나의 Screen을 구현한다.
* widnow 와 screen 은 다릅니다.
3. Activity LifeCycle
Activity 는 사진과 같은 LifeCycle 을 갖는다.
onCreate()
Android System 에서 Activity 를 Instance화하기 위하여 호출하는 메소드
* setContentView() 를 사용하지 않으면 어떻게 되나요? UI Layout이 없으니까 에러인가요?
onStart()
Screen 이 보여지는 순간에 실행됩니다.
어라? setContentView() 가 Screen 의 UI Layout 을 정의하는 거라면, 어짜피 보여질 때 onStart() 가 호출되니까 이때 setContentView() 를 사용해도 되지 않아요?
가능은 합니다. 그런데, 왜? setContentView() 를 onCreate() 에 쓰는걸까?
Docs 에 의하면,
onCreate() 활동이 처음 생성 될 때 호출됩니다. 여기에서 뷰 생성, 목록에 데이터 바인딩 등 일반적인 정적 설정을 모두 수행해야합니다.이 메서드는 활동의 이전에 고정 된 상태 (있는 경우)를 포함하는 번들도 제공합니다. 라고 되어있습니다. |
음? 으음? 싶으시다면, 한가지 예를 들어보겠습니다.
Bundle 에는 Activity Instance 의 상태들을 저장할 수 있습니다. ( 변수를 저장할수도 있습니다. ) 이때 Bundle 에 저장된 상태를 이용하여 layout 을 수정한다고 생각하면,
우리는 onStart() 에서 Bundle 에 접근하기 위한 대책을 추가해야합니다. (변수를 추가로 넣는 등)
또한 꼭 이 때문은 아니더라도, 문서에서 제공하는 onCreate() 의 정의에 맞게 사용하는게 옳바른 코드의 작성방법 이라고 할 수 있겠죠?
onResume()
이 메소드는 사용자와 상호작용을 하는 순간에 실행됩니다.
즉, 사용자의 터치이벤트, 키보드로 입력넣기, 핸드폰을 흔들 때 반응해야하기 등등은
이 메소드가 호출되어야 가능합니다.
Activity Running
만약 우리가 C,Java 등의 언어에서 main() 을 실행하고 종료되기 전까지는 Running 단계겠죠?
마찬가지로 onResume() 이 실행된 이후부터는 Running 단계입니다.
onPause()
이 메소드는 사용자와 상호작용을 하지 못하는 순간에 호출됩니다.
그렇다고, 화면이 사라지는 상태를 말하는 것은 아닙니다.
또한, 사용자와 상호작용을 하지 못할뿐, 화면에 사라진 상태는 아니기 때문에 UI 를 업데이트 할 수 있습니다.
* 위와같은 상황에서 다시 MainActivity 로 돌아간다면, MainActivity 가 사용자와 상호작용이 가능해지니까 onResume() 이 실행됩니다.
onStop()
이 메소드는 더이상 Activity 의 Screen 이, 사용자에게 보여지지 않는 순간에 실행됩니다.
하지만, Instance 가 없어진 상태는 아닙니다.
* 특정한 조건없이 1초마다 count를 증가하는 Thread 가 실행중이였다면, onStop() 이후에도 Thread는 멈추지 않고 count를 계속 증가시깁니다. 때에 따라서는 필요할수도, 굉장히 위험할수도 있습니다.
(불필요한 코드가 계속 돌고 있다는 것은 성능저하까지 이어질 수 있...)
onStop() 이후에 굳이 필요없는 코드는 잠시 멈춰두는 것을 추천합니다. 밑에 나오는 onRestart() 에서 다시 실행시키면 되죠!
onRestart()
onStop() 메소드가 실행된 이후에, Activity 의 Screen 이, 다시 사용자에게 보여지는 순간에 호출됩니다.
즉, onStop() 이후에 screen이 보여진다면 onStop() -> onRestart() -> onStart() 순으로 진행되고,
onCreate() 이후에 screen이 보여진다면 onCreate() -> onStart() 순으로 진행됩니다.
* onPause() 에서 onResume() 이 호출되고, onRestart()도 결국 onRestart() -> onStart() -> onResume() 이 호출되면서
onResume() 에 onStop() 이후에 얻어지는 데이터를 넣는 경우가 있습니다.
저는 onResume() 에서는 onResume() 상황에 맞는 코드.
onRestart() 에서는 onRestart() 상황에 맞는 코드 만을 작성하는 것을 추천합니다.
onDestroy()
이 메소드는 Activity 가 완전히 사라지는 순간에 호출됩니다. 문서에 의하면, 현재 Activity Instance 에서 finish 를 사용하는 경우에 호출되거나, Android System 에서 메모리절약을 위해 일시적으로 파괴하면서 호출이 된다고 하는데, 이는 isFinishing() 으로 구분이 가능하다고 작성되어 있습니다.
만약 finish 를 사용하거나, Back 키를 사용하는 등으로 Activity 가 사용자에 의해 파괴되는 경우에는 isFinishing() 은 true 를 반환합니다.
Android System 에서 메모리절약을 위해 파괴하는 거라면 false 를 호출합니다.
* onDestroy() 에서 isFinishing() 가 true 일 때 데이터를 저장하거나 하는 행위는 위험합니다.
( 쉽게 onDestroy() 에서 데이터를 저장하지 마세요. )
*Android System 은 Process 만을 kill 합니다.
*만약, Process 가 제거되는 순간을 경험하고 싶다면, 개발자옵션 -> 프로세스수제한 -> 개수선택
이후 다른 앱들을 실행시켜보세요. 개수가 가득차면 Process 가 제거되면서 false 를 리턴합니다.
4. 정리
1. Activity 는 Android System 가 콜백메소드(onCreate)를 호출하여 생성하며 콜백메소드(Create~Destroy)는 LifeCycle 에 맞게 호출된다.
2. Activity 는 UI Layout을 정의하여 screen에 보여줄 수 있고, 만약 UI Layout 을 정의하지 않는다면 빈 screen이 보여진다. 또한 UI 가 없기 때문에 사용자에 맞춤 기능이 아니라, LifeCycle 에 해당하는 작성된 코드들만이 실행된다.
3. 일반적으로 1개의 Activity 는 1개의 Screen 을 구현한다.
4. Activity 의 window 와 screen 은 다르다.
5. LifeCycle 은 onCreate() , onStart(), onRestart(), onResume(), onPause(), onStop(), onDestroy()로 이루어져있다.
onCreate() : Android System 에서 Actvitiy 를 Instance화 하는 순간
onStart() : Screen 이 보여지는 순간
onRestart() : onStop() 이후에 Screen 이 보여지려고 하기(onStart()) 직전
onResume() : 사용자와 상호작용이 일어나기 시작하는 순간
onPause() : 사용자와 상호작용이 끊어지는 순간
onStop() : Screen 이 보여지지 않는 순간 : 단 1pixcel 이라도 Screen 이 보여진다면, onStop() 에 진입하지 않는다.
onDestroy() : Code(finish) or 사용자에 의해(back or finish) or AndroidSystem 이 Process 를 kill 하는 순간 - isFinishing()으로 구분
5. 오늘의 결론
생명주기에 맞게 코드를 작성하고, Android 문서는 영어로 보거나, 영어와 한글을 같이 보자.
( Window 랑 Screen 을 둘다 "화면" 이라고 번역시켜놔서 뇌에 혼란이 엄청왔다. )
PS.
일반적으로 1Activity 는 1개의 Screen 을 구현한다. 라고 되어있는 부분에서
1Activity 에서 어떤 경우에 2개 이상의 Screen 을 구현하는지는 좀더 찾아봐야 할 것 같습니다.
여러 의견 모음 (2021.04.15 기준)
1. Fragment 를 이용하여 화면에 보여주는 View 가 다른데, 이런 경우에 2개 이상의 Screen 을 구현하는 것 같다.
- 저는 Activity 가 Window 에 Screen 을 보여주고, 이때 Screen 은 setContentView() 를 사용하여 정의한다고 되어 있는 부분에서 이 부분이 의아했습니다. Fragment 에 대해서는 추가 글에서 정리하겠지만, Fragment 는 Activity 이후에 나온 기술로, Activity 에 대해 설명하는 기준에 있어서 Fragment 를 사용하는 경우를 2개 이상의 Screen 을 구현했다고 생각하지 않습니다.
뭔가 근본적으로 Screen 에 대한 정의가 확실히 잡혀있지 않은 상태여서 그 부분을 찾아보고 있지만, Fragment 가 나오기 전부터 Screen 을 2개 이상 구현할 수 있었고, 그 로직의 단점을 보완하고자 Fragment 가 등장한것이 아닐까 라는 생각을 합니다.
이 부분에 대해 정확하게 설명이 가능한 블로그 or 지식을 보유중이신 분이 있으시다면 공유부탁드리겠습니다..
'BackUp (관리중지) > Android 이론' 카테고리의 다른 글
Android Service (0) | 2021.05.14 |
---|---|
Android Coroutine [코루틴] (0) | 2021.05.04 |
[Android Jetpack] LiveData란, (0) | 2021.04.21 |
Fragment 와 Fragment LifeCycle 분석 (0) | 2021.04.19 |
Android Context 에 대한 분석 (1) | 2021.04.14 |