코딩 (독학)/★ Kotlin

[Android : Kotlin] 안드로이드 액티비티 생명주기 총 정리 (Android Activity Life Cycle) / 안드로이드 4대 구성요소 (컴포넌트 - 액티비티)

짱득이 2022. 3. 27. 22:31
300x250
반응형

 


🐱‍🏍 Android Activity Life Cycle

안드로이드 액티비티 생명주기

 

안드로이드 기본 4대 구성요소 (컴포넌트)

액티비티의 생명주기를 알기 전에 간단히 액티비티는 무엇인가에 대해 알고 넘어 갈 필요가 있다.

먼저 위의 사진과 같이 안드로이드 어플리케이션은 기본적으로 4대 구성요소 (컴포넌트)로 구성되어 있다.

 

사진상으로 알 수 있듯이 각각 독립적인 형태로 존재 & 동작하면서 역할에 맞는 고유의 기능을 수행하게 되고,

Intent를 통해 서로 데이터를 주고받으며 통신한다.

 

이 중에서도 UI (= User Interface)와 가장 밀접한 관련을 가지고 있는것이 바로 Activity 단이며, 화면의 기본 구성단위가 된다.

즉, Android Application에 있어서 가장 기본이라고 할 수 있는 구성요소이고 대부분의 앱은 최소 한개 이상이 필수적이며 다수의 액티비티가 서로 연결된 형태로 구성되어있다고 볼 수 있다.

 


👀 액티비티 (Activity)

사용자에게 제공되는 UI가 있는 화면이다. 즉, 사용자와의 상호작용 (Interaction)을 담당하는 인터페이스이다.

 

* Activity의 주요 특징

  • 모든 Activity Class에 대하여 AndroidManifest.xml 내부에 <activity> 선언이 있어야한다.
  • Build가 성공적으로 이루어지려면 반드시 하나 이상의 Activity가 선언되어야 한다. (android.intent.action.MAIN)
  • Activity 내 Fragment를 선언하면 화면 분할이 가능하다.
  • 모든 Activity와 Service는 UI Thread (Main Thread)에서 동일한 Application Thread로 실행된다.
  • 실행된 Activity (Activity Instance)는 Stack에 Push되고 onBackPressed된다면 Pop 된다.
  • Activity의 생명주기에 따라 APP 또는 특정 Activity가 종료될 수 있다.
  • Intent (인텐트)를 통해 다른 Activity를 호출할 수 있다.
* Fragment는 앱의 구성요소가 아닌가?
 - Fragment는 Activity의 특징 일부를 물려받은 독자적인 생명주기를 가진 UI Component이다.
쉽게 말하면 Button, EditText 등과 같은 선상에 있는 개념이다.
그리하여 Fragment의 생명주기는 Activity가 활성화 된 상태 (실행중)에서 작동한다.

😎 액티비티 생명주기 (Activity Life Cycle)

출처 : https://programmingfbf7290.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0Activity-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

위 다이어그램을 참고하여 생명주기 각각의 단계에서 어떤 작업을 하면 좋을까 ?

 

* onCreate( ) : 초기화 처리, View 생성 등 (Activity 만들어지는 상태, 액티비티 생성할 때)

 - 콜백 메소드이며, Activity 생명주기의 생성 단계에서 최초로 Activity를 실행하면 처음으로 호출되는 함수.

 - Activity가 생성될 때 Override하며, 화면을 정의하는 용도로 사용. (완료되면 onStart( )가 호출됨.)

 - 초기화 관련 작업을 하면 좋다.

 - 생성 단계인 onCreate( )에서 setContentView( )에 아래와 같은 형태로 Layout을 전달하여 화면을 정의.

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	setContentView(R.layout.activity_main)
    } // 여기서 R은 resource -> res -> r 에 해당한다.
    // 즉 Resource/layout/activity_main.xml을 setContentView의 파라메터로 넘겨 화면을 정의한 것.

 - 아래와 같은 파라메터를 수신하며, 이것은 Activity의 이전 상태를 저장한 Bundle 객체이다.

savedInstanceState: Bundle?

 - Activity가 처음 생성 된 경우, savedInstanceState는 null 상태이다.

 - 이 외에도 dataBinding( ), viewBinding( ), Instance화 등의 작업을 할 수 있다.

 

 

* onStart( ) : 통신, 센서 처리 시작 등 (화면에 나타나있는 상태로, 화면에 보여지기 시작할 때)

 - 콜백 메소드이며, 이 시점부터 사용자가 Activity를 볼 수 있게 된다.

 - 단, 아직 사용자와의 상호작용 (Interaction)은 불가능하다.

 - ForeGround 상태에서 사용자와의 상호작용을 준비하는 단계이다.

 - 최초로 Activity를 실행하면 onCreate( ) 다음으로 호출되는 함수이다.

 - onStop( ) -> onRestart( ) 다음으로 호출되는 함수이기도 하다.

 

 

* onResume( ) : 필요한 애니메이션 실행 등 / 화면 갱신 처리 (화면에 나타나있는 상태로, 앱이 현재 실행중인 상태)

 - 이 시점부터 Activity가 활성화 된 상태 (실행중인 상태)로 본다.

 - 사용자와의 상호작용 (Interaction)이 가능한 단계로, Activity Stack의 TOP에 위치해있음

 - 주로 Application의 코어 기능이 onResume( ) 에 설정됨.

 - 사용자가 Activity에 대한 포커스가 없어질 때 까지 onResume( ) 상태가 지속됨.

 - 포커스가 사라지면 Activity가 일시중지 상태가 되며, onPause( ) 가 호출됨.

 - onPause( ) 상태에서 다시 Activity가 활성화 되면 onResume( ) 이 호출됨.

 - onResume( ) 이 호출되면 Activity가 재개될 때 필요한 초기화 작업을 수행

 - 최초로 Activity를 실행하면, onStart( ) 다음으로 호출되는 함수.

 - onPause( ) 다음으로 호출되는 함수이기도 함.

 

 

* onPause( ) : 애니메이션 등 화면 갱신처리에 대하여 정지, 일시정지 할 때 필요없는 Resource를 해제하거나 필요한 데이터를 😎영속화함. (액티비티 화면의 일부가 다른 액티비티에 가려진 상태)

 - Activity가 잠시 멈춘 단계.

 - Activity의 동작이 Background에 위치하게 됨.

   (멀티 윈도우 모드에서는 Activity가 백글가운드에 위치하게 되어도 화면에 보일 수는 있음.)

 - 상황에 따라 onStop( ) 또는 onResume( ) 상태로 전환이 가능해짐.

 - 만약 onResume( ) 이 호출 된 이후에 다른 Activity가 최상단에서 보여지는 경우 호출되는 함수.

   (즉, 현재 Activity가 onResume( )에 의하여 활성화 되어 포커스를 가진 이후 현재 Activity가 포커스를 잃게되는 경우)

    (ex : 전화가 왔거나, 다른 App을 잠시 실행시킨 경우)

 - 만약 onPause( ) 가 호출 된 이후에 다시 기존 Activity로 돌아오는 경우 onResume( )이 호출 됨.

   (즉, 다른 Activity가 Stack Top에서 보여진 이후 다시 기존 Activity로 돌아온 경우)

 - 만약 다른 앱이 메모리를 필요로 할 경우 App Process가 종료될 수 있음.

 - onPause( ) 단계에서 Activity가 Backgound에 있을 때 필요하지 않은 기능 (Resource)를 해제하는 동작을 할 수 있다.

 - 일반적으로 onPause( )가 지속되는 시간이 짧다. (이벤트를 수행하기 전 끝나는 경우가 생김)

 - 데이터 저장 또는 호출과 같은 Transaction은 사용하지 않는다.

 - 실행 시간이 긴 이벤트는 onPause( )가 아니라 Activity가 멈춘 onStop( ) 메소드에서 사용하여야 한다.

 

 

* onStop( ) : 통신, 센서 처리 정지 등 (다른 Activity의 실행으로 화면이 완전히 가려진, 없어진 상태)

 - Activity가 사용자에게 보이지 않는 단계로, onPause( ) 상태의 Activity가 이젠 완전히 중지되었을 때 호출 됨.

 - 상황에 따라 onDestroy( ) 또는 onRestart( ) 상태로 전환이 가능해짐.

(만약 onResume( )이 호출 된 이후에 다른 Activity가 최상단에서 보여지는 포커스를 잃고, Activity가 완전히 보이지 않는 경우 호출되는 함수.)

(만약 onStop( )이 호출 된 이후 다시 기존 Activity로 돌아오는 경우 onStart( )가 호출 됨.)

 - 사용자에 의한 경우 (onBackPressed( ) 호출 등) / 시스템에 의한 경우 (자원 부족 등) 에 의해 Activity가 완전히 종료되면 onDestroy( )가 호출 됨.

 - 만약 다른 앱이 메모리를 필요로 할 경우 App Process가 종료될 수 있음.

 - onStop( ) 메소드를 통해 Activity가 중지되었을 때 필요없는 Resource를 해제시키거나, 적절히 조정한다.

 - onStop( ) 메소드에서는 부하가 큰 작업 (데이터 처리, 저장 관련 트랜잭션)을 하기에 적절하다.

 

 

* onRestart( ) : 보통 아무 작업을 안하긴 함.

 - onStop( ) 상태였던 Activity가 재-시작 (Restart) 되는 단계

 - onRestart( ) 뒤에는 onStart( ) 콜백이 자동 호출 됨.

 

 

* onDestroy( ) : 필요 없는 Resource는 해제 / Activity의 참조 정리 (Activity 종료. 즉, 앱 종료)

 - Activity가 사용자에 의하거나 시스템에 의하여 완전 종료되는 경우에 호출되는 함수. (Activity 소멸 직전에 호출)

 - 사용자에 의하여 종료 된 경우, onBackPressed( ) 호출 / finish( ) 등의 경우가 있음.

 (* onBackPressed( ) 호출 시에는 기존 실행되었던 Activity가 onResume( ) 상태까지 Back 된 후 onDestroy( )가 호출 됨)

 (* 화면 구성 변경으로 Activity가 소멸 된 경우 (화면 회전, 멀티 윈도우 모드로 변경 한 경우에도 호출))

 - 시스템에 의하여 종료 된 경우, 대표적으로는 자원부족 문제를 해결하기 위한 메모리 확보의 경우가 있음.

 - onDestroy( ) 단계에서 ViewModel 객체를 이요하면 Activity의 View Data를 보관할 수 있다.

 - 화면 회전 등의 구성 변경으로 Activity가 종료 된 경우, 바로 새로운 Activity가 onCreate( ) 된다.

 - Activity에 있는 Data를 더 이상 쓰지 않는다면 onDestroy( ) 단계에서 모두 정리 해 주어야 한다.


 

✍ 액티비티 생명주기에서의 메소드 호출 순서

(Method Call Sequence in Activity Life Cycle)

1. 앱 시작 : onCreate( ) ➡ onStart( )  onResume( )

2. 화면 회전할 때 : onPause( )  onStop( )  onDestroy( )  onCreate( )  onStart( )  onResume( )

3. 다른 액티비티가 TOP STACK될 때 / 전원 키로 화면 꺼질 때 / 홈 키 눌러서 이동할 때 : onPause( )  onStop( )

4. Back (뒤로가기) 키로 Activity 종료 : onPause( )  onStop( )  onDestroy( )

5. 다른 액티비티 상태에서 Back 키를 통해 기존의 Activity로 다시 돌아올 때 / 홈 키로 나갔다가 돌아올 때

     onRestart( )  onStart( )  onResume( )6. 다이얼로그 액티비티 or 투명 액티비티가 화면에 뜰 때 : onPause( )


액티비티의 생명 주기의 라이프 타임

(Life-Time in Activity Life-Cycle)

* 전체 라이프 타임 : onCreate( ) ⏩ onDestroy( )

* 가시(Visible) 라이프 타임 : onStart( ) onStop( )

* 포어그라운드 라이프 타임 : onResume( ) onPause( )

    => 액티비티는 onPause( ) 이전까지 ForeGround이고, onPause( ) 까지 실행된다면 BackGround 상태가 된다.

    => 또한 onPause( )까지 화면 일부가 가시(Visible) 되고 onStop( ) 까지 실행되면 더 이상 Activity가 보이지 않는다.

    => onCreate( )에서 setContentView( )를 호출하지만 onCreate( ) ~ onResume( ) 까지는 하나의 메시지로 처리된다.

    => 따라서 onResume( ) 이후에 Activity가 시작된다.

 


 

😎 프래그먼트 생명주기 (Fragment Life Cycle)

Fragment는 Activity의 생명주기 아래에서 UI를 나타내는 용도로 독자적인 생명주기를 가지고 동작하기 때문에

안드로이드 4대 구성요소 중 Activity를 알았다면 Fragment는 필수적으로 함께 알아야 하는 부분이기 때문에 알아보자.

출처 : https://developer88.tistory.com/69

* onAttach( )

 - Activity에서 Fragment를 추가하면 호출 됨. (Attach 상태)

 - 인자(파라메터)로 Context를 받아서 Listener Interface를 Implement 한 경우에 Context를 통해 가져올 수 있음.

context : 맥락, 문맥

implement : 시행하다

* onCreate( )

 - onAttach( ) 다음으로 호출되는 함수.

 - Activity와 마찬가지로 초기화 해야하는 Resource들을 여기서 초기화 해 줌. (Activity에서의 onCreate( )와 비슷한 역할)

 - 단, UI 관련 작업은 할 수 없음. (View와 ViewGroup의 UI binding과 같은 작업들)

 - UI관련 작업 이외에 Int형 등등의 변수 초기화 등의 작업 정도는 가능. (프래그먼트를 생성하면서 넘겨준 값들이 있다면, 여기서 변수에 넣어주면 됨.

 

* onCreateView( )

 - onCreate( ) 다음으로 호출되는 함수

 - Layout을 Inflate하는 곳으로, View 객체를 얻을 수 있음.

 - 따라서 현재 시점부터 Fragment에 속한 UI 관련 작업을 할 수 있는 단계

 

 * onActivityCreated( )

 - Fragment에서의 onCreateView를 마치고, Activity 에서의 onCreate( ) 다음으로 호출되는 함수

 - Activity & Fragment의 View가 모두 생성 된 상태로, View를 변경하는 작업이 가능 한 단계.

 

* onStart( )

 - onActivityCreated( ) 다음으로 호출되는 함수.

 - Activity와 마찬가지로 이 시점부터는 사용자가 Activity를 볼 수 있음.

 

* onResume( )

 - onStart( ) 다음으로 호출되는 함수.

 - Activity와 마찬가지로 이 시점부터 Fragment가 활성화 된 상태 (실행중)으로 본다.

 

* onPause( )

 - Fragment의 Host Activity가 포커스를 잃고 다른 Activity가 최상단 스택에서 보여지는 경우 호출 됨.

 - 그러면 Fragment가 backStack 으로 들어감.

 

* onStop( )

 - Fragment의 Host Activity가 포커스를 잃고 다른 Activity가 최상단 스택에서 보여지는 경우 이면서, 이제 Activity가 완전히 보이지 않아버리는 경우 호출됨.

 

* onDestroyView( )

 - Fragment에 구현된 View가 제거되는 단계.

 - 이 메소드가 호출된 이후 기존 Fragment가 BackStack에서 돌아오면 onCreateView( )가 호출됨.

 

* onDestroy( )

 - Fragment를 완전히 제거하기 직전.

 

* onDetach( )

 - Fragment가 제거되고, Activity로부터 해제될 때 호출됨 (Detach)

 

※ Fragment 추가 참고

 - Activity의 onCreate( )기능을 Fragment에서는 두가지로 분리하였다. ( onCreate( ) / onCreateView( ) )

 - Activity의 onDestroy( )기능 역시 Fragment에서는 두가지로 분리되었다. ( onDestroy( ) / onDestroyView( ) )

 


액티비티와 프래그먼트의 생명주기 동작 프로세스

(activity and fragment life cycle operation process)

액티비티와 프래그먼트의 콜백을 로그로 살펴보면 아래와 같다.

* New Fragment Commit ! (First) * New Fragment Commit ! (Second) * onBackPressed called !
Activity : onCreate( ) 호출
Activity : Fragment_1 commit( )

Fragment_1 : onAttach( )
Fragment_1 : onCreate( )
Fragment_1 : onCreateView( )
Fragment_1 : onActivityCreated( )
Fragment_1 : onStart( )

Activity : onStart( )
Activity : onResume( )
Fragment_1 : onResume( )
Activity : Fragment_2 commit( )
Fragment_2 : onAttach( )
Fragment_2 : onCreate( )

Fragment_1 : onPause( )
Fragment_1 : onStop( )
Fragment_1 : onDestroyView( )
Fragment_1 : onDestroy( )
Fragment_1 : onDetach( )

Fragment_2 : onCreateView( )
Fragment_2 : onActivityCreated( )
Fragment_2 : onStart( )
Fragment_2 : onResume( )
Fragment_2 :  onPause( )

Activity : onPause( )

Fragment_2 : onStop( )

Activity : onStop( )

Fragment_2 : onDestroyView( )
Fragment_2 : onDestroy( )
Fragment_2 : onDetach( )

Activity : onDestroy( )

액티비티 전환 시 생명주기 메소드 호출

(Call Life-Cycle Method during Activity Transition)

Activity 전환 관련 메소드 호출 프로세스

 

 

아래 과정은 위의 경우와 반대로, 다른 Activity가 foreGround에서 다시 닫힐 때 기존의 Activity와의 동작 프로세스 과정이다.

 


생명주기 메소드 사용 관련 유의사항

* 리소스의 생성과 소멸은 대칭이 되는 생명주기 메소드에서 실행할 것.

예를 들어, onCreate( )에서 DB를 열었다면 onDestroy( )에서 닫아야 한다.

대칭 메소드 : onCreate ↔ onDestroy( ) / onResume( ) ↔ onPause( ) ↔ onStart( ) ↔ onStop( )

만약 onCreate( )에서 DB를 연 상태로 대칭이 아닌 onPause( )에서 DB를 닫게 되어버리면 오류가 발생할 수 있다.

 

예로, Activity_A에서 Activity_B로 전환하고, back 키를 눌러 Activity_A로 돌아왔을 때 onPause( ) 호출로 DB가 닫히긴 했지만, 다시 돌아왔을 때 onCreate( ) 호출이 되지 않아 DB가 열리지 않는 상황이 발생할 수 있다.

이와 같은 상황을 방지하기 위해 대칭이 되는 생명주기에서 리소스 생성, 소멸 관련 동작을 해야한다.

 

* 생명주기의 super 메소드를 호출할 때 주의 할 사항

onCreate( ), onStart( ), onResume( ) 메소드는 super 클래스의 해당 함수를 호출하고 작업해야 한다. (작업 전 사전 호출)

onPause( ), onStop( ), onDestroy( )는 작업을 하고 super 클래스의 해당 함수를 호출해야 한다. (작업 후 사후 호출)

 

추가적으로 생명주기 콜백 메소드들을 직접 호출하는 것은 추천하지 않는다. 만약 호출을 해야 한다면 별도의 메소드를 정의하여 해당메소드를 호출하는 것을 권장한다.

 


* 참고
https://developer.android.com/guide/components/activities/activity-lifecycle

https://velog.io/@eun3673/application-fundamentals-lifecycle

https://androman.tistory.com/58?category=745053

https://programmingfbf7290.tistory.com/entry/%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%95%A1%ED%8B%B0%EB%B9%84%ED%8B%B0Activity-%EC%83%9D%EB%AA%85%EC%A3%BC%EA%B8%B0-%EC%B4%9D%EC%A0%95%EB%A6%AC

https://brunch.co.kr/@mystoryg/80

https://bbaktaeho-95.tistory.com/62
728x90
반응형