인턴 생활을 자발적으로 그만두고(!) 새로운 회사에 들어가고 단 한번도 생각해보지 않았던 앱 개발을 맡게 되어서 어떻게든 살아남기 위해서 발버둥치다보니 어느새 입사하고 1년이라는 시간이 지나버렸네요 😅

그동안 이런저런 일들을 하며 정신없이 시간을 보내다보니 정말 오랜만에 글을 쓰게 되는 것 같습니다!

 

앞으로는 이전처럼 FE 관련 글도 올라오겠지만, 현업에서 사용하고 있는 KotlinAndroid에 대한 글들도 많이 올라가게 될 것 같습니다!

 

아무래도 Android 앱 개발팀에서 일을 하다보니, 기존과는 다르게 Kotlin과 Android에 대한 지식들이 필요해졌습니다. (심지어 현재 회사에 들어올 때도 FE로 면접을 보고 들어왔다보니 앱 개발 취준생이 가진 기본적인 면접 지식들도 부족합니다 ㅠㅠ)

 

게다가 이와 관련된 다양한 업무들을 처리하기 위해서는 그때그때마다 산발적으로 공부해야 했는데, 이 때 부분적으로 익혔던 내용들을 보다 깔끔하게 정리하며 복습하는 용도로 블로그를 운영해 보려고 합니다 ㅎㅎㅎ

 

그렇다면 오늘은, 안드로이드 개발에서 가장 핵심이 되는 Activity의 생명주기에 대해서 알아보도록 하겠습니다!

 

목차


    0. Activity가 뭘까

    우리가 사용하는 애플리케이션은 각각의 화면들로 이루어져있습니다.

    어떤 앱에서는 로그인 화면이 있을거고, 메인 화면이 있을거고, 결제 화면이 있을 수 있겠죠?!

    이런 화면들 하나하나Activity라고 볼 수 있게 됩니다.

     

    이러한 ActivityUI를 작성하는 하나의 도화지라고 볼 수 있습니다.

    Activity라는 도화지에 우리가 볼 수 있는 다양한 요소들이 들어가게 되고, 사용자와 상호작용할 수 있게 되는 것이죠.

     

    그리고 각 도화지들이 서로 분리되어 있어서 언제든지 꺼내서 보거나 쓸 수 있는 것처럼,

    Activity 역시 분리되어 있기 때문에 서로 다른 진입점을 가지고 있습니다.

     

    메인 화면 Activity에서 어떤 버튼을 클릭해서 결제 화면 Activity로 넘어갈 수도 있고, 아예 다른 웹 환경에서 버튼을 클릭했을 때 바로 결제 화면 Activity로 넘어갈 수도 있습니다.

     

    이처럼 각각의 Activity는 기본적으로 언제든지 분리해서 사용할 수 있는 독립적인 존재입니다.

     

    출처:https://dinfree.com/lecture/android/android_3.1.html

     

     

    아래 링크는 액티비티에 대해 잘 설명이 되어있는 Android Developers에 작성된 글입니다. (영어 주의!)

     

     

    Activity  |  Android Developers

     

    developer.android.com

     

    Activity에 대해서 계속 공부하다보면 볼 수 있는 다른 개념들이 꽤 많이 존재합니다.

    가장 대표적으로 Activity 사이에서 데이터를 전달하기 위한 용도로 사용되는 Intent,

    복잡해지는 Activity를 보다 단순화하고 재사용이 용이하도록 모듈화 하는 용도로 사용되는 Fragment 정도가 있겠네요!

     

    이런 요소들은 오늘의 주제에서 약간 벗어나기 때문에 해당 포스팅에서는 이정도로만 알아보고 넘어가겠습니다 😊

     


    1. Activity의 생명주기가 뭘까

    이제 오늘 포스팅의 핵심 주제인 생명주기에 대해서 보다 자세히 알아보도록 하겠습니다.

     

    아래 그림은 우리가 오늘 공부해야 할 내용의 알파이자 오메가, 사실상의 전부입니다.

    안드로이드 개발을 하신다면 아래 Activity의 생명주기 그림,

    조금 더 자세하게 말하면 생명주기함수를 기반으로 한 다이어그램은 확실하게 공부하고 넘어가셔야 될 겁니다.

    (안그러면 저처럼 코드리뷰 받다가 호되게 혼날 수 있습니다 🤣)

     

    출처 : https://developer.android.com/reference/android/app/Activity

     

    위 그림을 확실하게 파악했다면, 아래와 같이 Activity의 상태 중심으로 그려진 그림도 쉽게 이해할 수 있게 되겠죠?

    이 포스팅을 모두 읽었을 때 쯤이라면 두 그림이 의미하는 바를 단번에 파악하실 수 있게 될 겁니다!

     

    출처:https://developer.android.com/codelabs/basic-android-kotlin-compose-activity-lifecycle#2

     

     

    안드로이드 환경에서는 각각의 Activity들이 위와 같은 생명주기를 예외 없이 따라가게 됩니다.

    각 단계들에서 동작이 필요한 부분이 있다면 콜백 형태의 메서드(생명주기함수) 내부에 구현되어야 합니다.

     

    간단한 예시를 들어보겠습니다.

    유튜브에서 어떤 영상을 보고 있는데, 갑자기 친구한테 전화가 왔습니다.

    이 때 유튜브 재생 화면 대신 전화 화면이 보이게 되겠죠?

    그런데 전화를 하면서 동시에 영상이 재생이 되어버리면 전화 소리와 영상 소리가 섞여 난감한 상황이 발생할 수 있습니다.
    이걸 막기 위해서는 전화가 왔을 때 잠시 영상을 멈추는 동작을 어느 순간에 해야겠다는 생각이 들죠?!!

     

    바로 위와 같은 상황을 처리하기 위해서 특정 생명주기함수(onStop) 안에 원하는 동작(영상 멈추기)을 넣음으로써 우리가 원하는 대로 애플리케이션을 동작하게 만들 수 있습니다.

    만약 Activity의 생명주기를 모르는 상태에서 위와 같은 상황을 마주한다면 생각대로 애플리케이션이 동작하게 만들기 위해서 한참을 삽질해야 할 지도 모릅니다.

     

    이제 왜 생명주기를 꼭 알고 있어야 하는지 아시겠죠?!!

    그렇다면 Activity의 탄생과 소멸까지의 과정중에 발생할 수 있는 5가지의 상태7가지의 생명주기함수에 대해서 더 자세하게 알아봅시다.

     

     


    2. Activity의 5가지 상태

    Activity에 생명주기가 있다는 말은, 특정한 상태에 따라 생성과 소멸을 하게 된다는 말과 동일합니다.

     

    기본적으로 생성(Initialized)소멸(Destroyed)이라는 상태를 가지고 있고, 그 사이에 보여지는지 여부와 포커스 가능 여부에 따라 3가지의 상태(Created, Started, Resumed)가 추가됩니다.

     

    상태 자체는 크게 어렵지 않죠?각각의 개념은 아래에서 추가로 설명하겠습니다.

     

     

    아, 개념을 설명하기 전에 Android 내에서 Activity의 상태가 어떻게 사용되는지에 대해서 간단하게 설명하고 넘어가겠습니다. 어떤 방식으로 쓰이는 지는 알아야 하니까요!

     

    기본적으로 Android의 운영체제는 Activity들을 Stack형태로 관리합니다.

    그리고 이 Stack을 Back Stack이라고 부릅니다.

    Stack의 개념에 대해서 잘 모르신다면.. 자료구조 카테고리의 stack 글을.. ㅋㅋㅋㅋ

     

     

    [자료구조] 스택(stack), 큐(queue)

    오늘은 자료구조의 가장 기본이 되는 스택과 큐에 대해서 알아보도록 하겠습니다! 목차 0. 스택 스택(Stack)이란 이름 그대로 순서대로 쌓인 무언가를 의미합니다. 우리가 뭘 쌓을 때 아래 요소를

    ssocoit.tistory.com

     

     

    아무튼!! Stack방식을 사용해서 Activity를 관리한다는 말은,

    Activity가 새롭게 띄워질 때마다 Stack의 top 위치에 새로운 Activity가 올라가는 방식이라는 말과 동일합니다.

     

    반대로 뒤로가기 버튼을 누르게 되면 Stack에서 pop되어서 이전 Activity가 Stack의 top에 위치하게 됩니다.

    top 위치에 있는 Activity를 Foreground Activity라고 부르고, 포커스를 가질 수 있는 Resumed 상태가 됩니다.

    나머지 Activity들은 화면에 보여지는지 여부에 따라 Created 상태이거나 Started 상태인 것이죠.

     

    아래 사진을 보면 이해하기 쉽습니다.

     

    출처:https://developer.android.com/guide/components/activities/tasks-and-back-stack?hl=ko

     

    만약 동일한 Activity가 두번 뜨게 되면 어떻게 될까요?

    기본적으로는 Stack이 새롭게 정렬되는 것이 아니라, Activity의 새로운 인스턴스가 생성되어서 Back Stack에 추가됩니다.

    같은 Activity의 다른 인스턴스가 Back Stack에 들어가게 되는 것이고, 서로 다른 인스턴스인 만큼 UI도 각각 관리됩니다.

    (엄밀히 말하면 Back Stack에는 Activity 자체가 들어가는게 아닌 Activity로부터 생성된 인스턴스가 들어가는 것이죠. 하지만 편의상 Activity로 말하는 경우가 많습니다 ^^;;)

     

    그래서 아래 사진처럼 중복된 Activity가 2개 들어갈 수도 있습니다.

     

    출처 : https://developer.android.com/guide/components/activities/tasks-and-back-stack?hl=ko

     

    물론 Activity의 속성값이나 Intent 플래그를 통해서 하나의 Activity로부터 생성된 인스턴스는 반드시 하나만 존재하는 상태로 Back Stack에 들어가도록 조절하거나 할 수 있는데, 이 부분도 오늘 포스팅의 범위를 넘어가므로 관련 링크로 간단하게 넘어가도록 하겠습니다.

     

     

    작업 및 백 스택  |  Android 개발자  |  Android Developers

    작업은 사용자가 앱에서 어떤 작업을 하려고 할 때 상호작용하는 활동의 모음입니다. 이러한 활동은 스택(백 스택)에 각 활동이 열린 순서대로 정렬됩니다.

    developer.android.com

     

    Activity의 상태를 설명하려다가 경로이탈을 엄청나게 해버렸네요 ^^;;;

     

    이왕 이렇게 된거 상태에 대해서 하나하나 알아보기 전에

    실제로 잘 구현이 되어있는지 여부도 코드로 직접 보고 넘어갑시다!!

     

    Androidx.lifecycle 패키지를 뜯어보면 아래와 같은 State 클래스를 볼 수 있습니다.

    DESTROYED, INITIALIZED, CREATED, STARTED, RESUMED 이렇게 총 5개의 상태가 존재함을 알 수 있습니다.

    사실 아래 사진만 봐도 쉽게 이해 가능할 수도 있습니다 ^^;;

     

     

    2.0. Initialized

    LifecycleOwner에 의해서 처음으로 Activity가 만들어졌을 때의 상태입니다.

    메모리에 Actvitiy의 인스턴스가 올라가있는 최초의 상태이자, onCreate() 라는 생명주기함수가 동작하기 전의 상태입니다.

    해당 상태는 처음 Activity가 생성되었을 때만 존재하는, 즉 굉장히 짧은 시간만 존재하는 상태라고 볼 수 있습니다.

     

    2.1. Created

    onCreate() 혹은 onStop() 이 동작한 직후의 상태입니다.

    Activity에 UI가 그려져서 화면에 보여질 준비가 된 상태를 의미합니다.

    준비만 됐다 뿐이지 화면에는 아직 보여지지 않는 상태입니다.

     

    따라서 메모리가 꽉 찬 경우 Created된 Activity는 다른 상태들보다 메모리에서 우선 제거 대상이 됩니다.

    게임 등 메모리를 많이 사용하는 작업을 하다가 다른 작업으로 넘어갔다가 다시 돌아가는 경우 게임과 같은 메모리를 많이 사용하는 작업이 강제로 재시작되는 경우가 있는데, 이 케이스가 바로 운영체제가 onStop() 생명주기함수에 의해 Created 상태가 된 Activity를 메모리에서 제거한 케이스입니다.

     

    2.2. Started

    onStart() 혹은 onRestart() 가 동작한 직후의 상태입니다.

    또는 onPause()가 동작한 직후의 상태이기도 합니다.

    사용자가 Activity를 볼 수는 있으나 포커스를 가지지 않아서 입력할 수 없는 상태를 의미합니다.

    사용자가 Activity를 더이상 볼 수 없게 된 경우에도 반드시 Started 상태를 거쳐서 Created 상태로 가게 됩니다.

    (onPause()와 onStop()이 모두 실행된다는 말과 동일합니다)

     

    2.3. Resumed

    onResume() 이 동작한 직후의 상태입니다.

    사용자가 Activity와 상호작용할 수 있는 상태를 의미합니다.

    사용자가 볼 수 있으며포커스되어 있어서 입력을 받을 수 있는 상태를 말합니다.

     

    2.4. Destroyed

    onDestroy() 이 동작한 직후의 상태로, Activity가 종료된 경우를 의미합니다.

    Created 상태의 Activity가 운영체제에 의해 메모리에서 제거된 경우 역시 Destroyed 상태가 된다고 볼 수 있습니다.

    다시 사용하기 위해서는 재시작해야하는 것이죠.

    이 상태 역시 매우 짧은 시간만 존재하는 상태입니다.

     

     


    3. Activity의 생명주기함수

    이번에는 생명주기함수(생명주기메서드)입니다.

    Activity의 상태 변화에 따라 자동으로 실행되는 함수라고 보시면 됩니다.

     

    이번에도 구현된 코드를 보고 개념으로 넘어가도록 하죠.

     

    아래 사진은 androidx.lifecycle의 Event 클래스를 가져온 사진입니다.

    아까 분명히 onRestart()라는 생명주기함수가 있었는데..?

    여기서는 onRestart가 없어서 의아할 수 있지만!!

     

     

    Activity 클래스 내부 구현 코드에는 아래와 같은 함수들이 정의되어있습니다.

    여기에는 onRestart가 존재하죠.

    이렇게 나눠진 이유는 아래에서 더 자세하게 알아보겠습니다!

     

     

    3.0. onCreate()

    Activity가 생성되었을 때 가장 먼저 호출되는 함수입니다.

    onDestroy()와 함께 전체 생명주기에서 단 한번만 수행되는 함수입니다.

    보통은 Layout을 정의하거나, View를 생성하고 DataBinding하는 부분들이 여기에 들어가게 됩니다.

     

    매개변수에 savedInstanceState가 들어가는데, 만약 상태가 보관되어 있는 경우 이 번들 객체를 가져와서 사용할 수도 있습니다.

     

    이 생명주기함수가 동작한 이후에는 반드시 onStart()가 따라나옵니다.

     

    3.1. onStart()

    Activity가 사용자에게 보여지기 직전, Started 상태로 가기 직전에 호출됩니다.

    만약 바로 Foreground로 표시되어서 포커스를 가져가는 경우에는 onResume() 생명주기함수가 뒤따라 동작하게 됩니다.혹은 모종의 이유로 사용자에게 더이상 보여지지 않는 경우 onStop() 생명주기함수가 뒤따라 동작하게 됩니다.

     

    3.2. onRestart()

    Activity가 사용자에게 보여지기 직전, Started 상태로 가기 직전에 호출되는 것은 onStart()와 동일합니다.

     

    하지만 onRestart()는 최초에 onCreate()에 뒤따라서 Started 상태로 가는 경우에는 호출되지 않고,

    onStop()이 된 이후에 새롭게 Started 상태로 가는 경우에만 동작합니다.

     

    그리고 onStart()보다 항상 먼저 동작하고, 함께 동작합니다.

    (onRestart만 동작되는 경우는 없습니다!)

     

    아래 onRestart()의 주석을 보면 확인할 수 있죠.

    (It will be followed by onStart~)

     

     

    onStop()의 구현을 봐도 다시 Activity가 Started 상태로 돌아가는 경우 onStart()가 아닌 onRestart()를 부른다는 것을 확인할 수 있습니다.

     

     

    어짜피 onRestart()가 동작하는 것은 항상 onStart()와 함께하기 때문에,

    onRestart()의 동작은 ON_START라는 이벤트로 함께 처리해도 무방하다고 볼수 있어서 위에서 확인한 Event 클래스에서는 ON_RESTART라는 이벤트를 만들지 않았다고 추측할 수 있습니다.

     

    3.3. onResume()

    Activity가 사용자의 포커스를 받을 수 있는 Resumed 상태가 되기 직전에 호출됩니다.

    Resumed 상태에서 이어서 동작할 수 있는 생명주기함수는 onPause() 뿐입니다.

     

    3.4. onPause()

    다른 Activity가 포커스를 받을 수 있는 Resumed 상태가 되었을 때 호출됩니다.

    만약 다른 Activity에 의해서 화면에 보이지 않는 상태가 되었을 경우 onStop()이 이어서 호출됩니다.

    물론 이 상태에서 다시 Activity가 활성화되어 포커스를 받을 수 있게 되는 경우 onResume()이 호출됩니다.

     

    3.5. onStop()

    Activity가 사용자에게 더이상 보이지 않게 되는 경우 호출됩니다.

    이렇게 Created 상태로 되돌아간 Activity가 사용자에게 화면을 보여주기 위해 Started 상태, 혹은 Resumed 상태로 가는 경우 onRestart() -> onStart() -> *onResumed() 순서대로 생명주기함수가 실행됩니다.

    (onResumed()는 Resumed 상태가 되는 경우에만 실행됩니다!)

     

    아니면 앗싸리 onDestroy()로 Activity가 삭제될 수도 있겠죠?!

     

    3.6. onDestroy()

    Activity가 메모리에서 사라지기 직전에 호출됩니다.

    모종의 이유로 Activity가 finish() 처리 되었거나, 운영체제에 의해 강제로 메모리에서 할당해제되었을 경우 동작합니다.

    (이 두 케이스의 경우 isFinishing() 메서드를 통해서 구분할 수 있다고 합니다)

     

     

    Activity  |  Android Developers

     

    developer.android.com

     

    그리고 onCreate()와 함께 전체 생명주기에서 단 한번만 수행되는 함수입니다.

     

     


    4. 정리

    지금까지 Activity의 생명주기에 대해서 알아보았습니다.

     

    위에서 이야기했듯이, 생명주기를 모르는 상태에서 개발을 한다면 애플리케이션의 정상 동작을 보증하기 어렵고, 추후에 문제가 발생한다고 했을 때 문제 파악에 있어서 어려운 부분들이 발생할 여지가 굉장히 많습니다.

     

    그러므로 조금이라도 헷갈리는 부분이 있다면 확실하게 알고 넘어가는 것이 훌륭한 애플리케이션을 만드는 데에 있어서 튼튼한 기반이 될 것이라고 생각합니다.

    (괜히 빈출 면접 질문이 아니겠죠? 😁)

     

    추가로 코드를 작성하면서 직접 Lifecycle에 대해서 이해해보고 싶은 분들이 있다면 아래 코드랩을 진행하시면 도움이 되실겁니다 ㅎㅎ

     

     

    Android 기초 02.2: Activity 수명 주기 및 상태  |  Android Developers

    이 Codelab에서는 TwoActivities 앱에 로깅 문을 추가하고 활동 수명 주기 변경사항을 확인합니다. 이러한 변경사항을 사용하여 이러한 조건에서 사용자 입력을 처리하는 방법을 살펴봅니다.

    developer.android.com

     


    5. 참고자료

     

    Activity  |  Android Developers

     

    developer.android.com

     

    안드로이드 기초

    안드로이드 액티비티의 라이프사이클을 알아보고 시스템에서 액티비티가 관리되는 방식과 라이프사이클 변화에 따라 개발자가 처리해 주어야 할 작업들을 배웁니다.

    dinfree.com

     

    작업 및 백 스택  |  Android 개발자  |  Android Developers

    작업은 사용자가 앱에서 어떤 작업을 하려고 할 때 상호작용하는 활동의 모음입니다. 이러한 활동은 스택(백 스택)에 각 활동이 열린 순서대로 정렬됩니다.

    developer.android.com

     

    활동 수명 주기 단계  |  Android Developers

    이 Codelab에서는 활동 수명 주기와 로깅을 알아봅니다.

    developer.android.com

     

    반응형
    • 네이버 블로그 공유하기
    • 네이버 밴드에 공유하기
    • 페이스북 공유하기
    • 카카오스토리 공유하기