안드로이드 [Kotlin] - Task와 Launch Mode 그림으로 이해하기
- 안드로이드 시스템은 자동으로 Task를 관리하지만, Launch Mode를 통해 Activity가 Task에 관리되는 방식을 설정할 수 있다.
- 즉 Activity 실행 시 쌓이는 Task(Back Stack)에 대한 운영 방식을 우리가 설정할 수 있다는 뜻이다.
여기서 Task와 Back Stack의 차이를 공식문서에서는 이렇게 말하고 있다.
https://developer.android.com/guide/components/activities/tasks-and-back-stack
작업 및 백 스택 이해 | Android 개발자 | Android Developers
일반적으로 앱에는 여러 활동이 포함됩니다. 각 활동은 사용자가 실행할 수 있는 특정 종류의 작업을 중심으로 설계되어야 하며 다른 활동을 시작할 수 있어야 합니다. 예를 들어 이메일 앱에는
developer.android.com
A task is a collection of activities that users interact with when trying to do something in your app. These activities are arranged in a stack—the back stack—in the order in which each activity is opened.
즉 ‘ Task가 어플리케이션에서 실행되는 액티비티를 보관하고 관리하는 역할을 수행하며 그 형태가 스택이고, 이 스택을 백스택이라고 부른다’ 로 이해하면 된다.
📌 Task란?
Task는 한마디로 말하면 애플리케이션에서 실행되는 Activity를 기록하는 스택이다.
- Task는 안드로이드 OS에 존재하는 프로세스 내부에 존재하는 개념이다.
- 안드로이드 OS는 Activity 단위로 동작한다.
- 만약 우리가 앱을 클릭하여 시작하게 되면 안드로이드 OS는 이전에 존재하던 Task가 있는지 보고 있다면 우리가 있었던 그 위치에 되돌려 보내준다.
- 만약 아무런 Task가 발견되지 않는다면 새로운 Task를 실행하여 Activity를 실행하게 되고 그 Activity를 Back Stack의 Base Activity로서 시작하게 된다.
📌 Process vs Task
Process
- Process의 경우 다른 운영체제와 동일하게 애플리케이션의 독립적인 실행 단위를 말한다.
Task
- Task는 안드로이드에서 Process와 무관하게 실행되는 Activity의 정보를 저장하고 있다.
- Task를 통해 애플리케이션의 화면의 흐름을 관리할 수 있다.
즉 Process는 해당 애플리케이션에 존재하는 모든 객체와 변수들을 포함하지만, Task는 애플리케이션의 실행되는 Activity을 포함하며 다른 Process의 Activity 또한 포함할 수 있다. 이를 그림으로 표현하면 다음과 같다.
애플리케이션을 실행하게 되면 Process와 Task가 각각 실행된다.
- 1번 애플리케이션을 실행하면 Process #1와 Task가 생성된다.
- 어떤 기능을 통해 그 상태에서 2번 애플리케이션이 실행한다.
- 2번 애플리케이션의 Process #2가 실행된다.
- 2번 애플리케이션의 Activity #2는 1번 애플리케이션을 실행했을 때 생긴 Task에 저장된다.
- Activity의 인스턴스는 해당 앱 Process의 메모리 영역에 생성되고, 호출하는 앱의 Task에서 해당 인스턴스를 참조한다.
이렇게 2번 애플리케이션을 실행해서 Activity #2를 열거나 Back 버튼을 눌러서 Activity가 전환되면 현재 Acitivty에 해당되는 Process로 전환되는 것이다. 그리고 Activity 참조가 끝나고 Task에서 제거될 경우 해당 Process도 종료된다.
📌 Launch Mode
위에서 설명한 것처럼 Android에서 Task라는 것이 존재하기 때문에 이를 관리하는 방법 역시 존재한다.
이와 관련하여 Task를 관리할 수 있는 속성들 중 Launch Mode에 대해 공부해보자.
Launch Mode를 통해 액티비티의 새 인스턴스가 현재 Task와 연결되는 방식을 정의할 수 있다.
Launch Mode를 정의하는 방법은 두 가지가 존재한다.
- Manifest 파일에서 액티비티를 선언할 때 지정할 수 있다.
- startActivity()를 호출할 때 새 액티비티에 Launch Mode를 선언하는 플래그를 Intent에 포함할 수 있다.
위 두 가지 방법 중 manifest 파일을 사용할 때 Launch Mode를 선언할 수 있는 4가지 속성이 있다. 이를 하나씩 살펴보자
1. Standard (기본 값)
모든 Activity가 Standard로 선언되어 있는 경우 가정
- 기본적으로 설정되는 디폴트 값이다.
- Activity에 대한 새로운 인스턴스가 생길 때마다 쌓아 올린다. (그것이 같은 인스턴스라고 할지라도)
2. SingleTop
A와 B가 모두 SingleTop으로 선언되어 있는 경우 가정
- SingleTop의 경우 '가장 상위에' 같은 인스턴스가 있으면 올라가지 않는다.
- SingleTop의 경우 대상 Task의 Stack 상단에 이미 해당 Activity의 인스턴스가 있는 경우 onNewIntent() 메서드를 호출하여 기존의 Activity 인스턴스를 재활용하게 된다.
- 위 그림에서 3번째에서 4번째로 넘어갈 때, 즉 B가 가장 상위에 있는 상태에서 A를 실행하는 경우에는 B가 가장 상위에 있지 않으므로 A 인스턴스가 정상적으로 올라가게 된다.
3. SingleTask
C만 SingleTask로 선언되어 있고 나머지는 Standard 즉 기본값인 경우 가정
SingleTask의 경우 두 가지의 상황을 살펴보자
- 새로운 Activity를 호출할 경우
- 기존 Activity를 호출할 경우
💡 새로운 Activity를 호출할 경우
💡 다른 Task에 이미 존재하는 Activity를 호출할 경우
- SingleTask 모드로 설정된 Activity가 Task에 존재하지 않는다면 새로운 Task에서 열린다.
- 이미 Task가 생성된 상태에서 다시 SingleTask로 설정된 Activity가 다시 호출될 경우 onNewIntent() 메서드를 통해 해당 Activity를 재사용한다.
- 즉 startActivity를 두 번 연속 호출했다고 가정하면 첫 번째는 onCreate()부터 호출되고 두 번째는 onNewIntent() -> onResume() 순서로 호출된다.
- 여기서는 SingleTop처럼 가장 위의 Stack과 비교하는 것이 아니다.
4. SingleInstance
A, B, C 모두 SingleInstance로 선언된 경우 가정
- SingleTask와 동일하게 Activity 호출 시 항상 새로운 Task가 생성된다.
- 하지만 SingleInstance는 하나의 Task에 하나의 Activity만 존재할 수 있다.