이번 우테코 레벨2 미션을 진행하면서 intent flag에 대해 공부하다가 Task라는 단어를 마주쳤습니다 🤓
Task가 무엇인지, 어떻게 관리할 수 있는지 알아 보고 기록해 보려고 합니다 🥲
Task는 어플리케이션에서 실행되는 액티비티를 기록하고, 보관 & 관리합니다
앱에서 무언가를 수행할 때 상호 작용하는 액티비티들은 각 액티비티가 실행된 순서대로 Back Stack에 기록됩니다
이때 최초로 시작하는 액티비티 (앱의 시작점)을 Root Activity라고 부르며, 어플리케이션 런처로부터 실행됩니다
마지막으로 호출된 액티비티는 Top Activity라고 부르며, 현재 활성화 되어 있는 액티비티를 뜻합니다
새 Activity를 시작하면 이전 Activity 위로 새로운 Activity가 스택에 쌓이면서 시작됩니다
이때 이전 Activity는 현재 상태를 보존하고, 스택에 남으며 중지됩니다 😵💫
A activity가 B activity를 호출했다고 가정해 볼까요 ? 🤔

이렇게 A activity위로 B activity가 stack에 push 됩니다
이후에 사용자가 뒤로 가기 버튼을 누르면 B Activity 가 pop 되고, A Activity가 Top Activity로 돌아갑니다

만약 B Activity 위에 다른 Activity가 있고, 다시 A Activity를 호출한다면 어떻게 될까요?

이렇게 스택에 A activity가 두 개 쌓이게 되겠군요 🤔
이런 식으로 Back stack에 쌓이는 Activity들을 관리하지 않는다면 어떤 일이 발생할 수 있을까요?
생성한 Activity들을 계속 Back stack에 쌓이게 둔다면, 사용자가 뒤로 가기를 누를 때 예상치 못한 화면으로 이동할 수 있을 것 같아요 🤓
또한 쓸모없는 Activity들이 메모리에 쌓여서 앱 성능이 나빠질 수도 있겠네요 🤯
이 Activity들을 관리하기 위해 Intent flag를 사용할 수 있다고 합니다
사실 intent flag로 사용할 수 있는 플래그는 정말 많은 종류가 있는데요 ... ! 🥲
이번 글에서는 많은 플래그들을 다루지 않고, 공식 문서에서 소개한 주요 플래그 3가지를 다뤄 보겠습니다
새로운 task를 생성하여 그 task 안에 activity를 추가할 때 사용합니다
다만, 기존에 존재하는 task들 중에 생성하려는 Activity와 동일한 affinity를 가지고 있는 task가 있다면 그곳으로 Activity가 들어가게 됩니다
💡 affinity란?
간단하게 말해서 activity가 어떤 task에 속하고 싶은지? 를 나타내는 속성이다
AndroidManifest.xml파일에서android:taskAffinity로 설정할 수 있다
_
기본적으로 같은 앱의 activity들은 모두 같은 affinity를 가진다
명시적으로 바꾸지 않으면 패키지명이 기본 affinity이다

예시로 task가 위와 같이 생성되어 있다고 가정해 보겠습니다 🤔
( 각 스택에 들어가 있는 것은 Activity의 affinity 입니다 ! )
android:taskAffinity="com.app.pay"로 affinity를 지정해 주고,
FLAG_ACTIVITY_NEW_TASK 플래그를 달아 activity를 생성한다고 가정해 보겠습니다
생성할 때 다른 task들 중에 com.app.pay를 가진 task가 있는지 탐색하고,
com.app.pay를 affinity로 가진 task가 없으므로 해당 Activity가 생성되면서 새로운 task가 생성될 것입니다

그림으로 보면 task3이 새로 생기고, 그 안에 실행할 Activity가 들어갈 것입니다
하지만 affinity로 com.app.pay가 아닌, com.app.chat이었다면 어떻게 됐을까요?

task2가 com.app.chat을 affinity로 갖는 Activity를 들고 있으므로 task2로 들어가겠네요 💪
현재 task에 실행하려는 Activity가 이미 실행 중이라면, 새로운 인스턴스를 생성하는 대신 그 위에 쌓여 있던 다른 Activity들을 모두 종료합니다
stack에 A -> B -> C 순서대로 Activity가 쌓여 있고,
C가 A를 startActivity()로 호출한다고 가정해 봅시다 🙃
intent에 아무 flag도 지정해 주지 않는다면 아래 그림처럼 C 위에 A Activity가 쌓이겠군요 🤔

intent에 FLAG_ACTIVITY_CLEAR_TOP 플래그를 지정해 준다면 A Activity위에 쌓여 있던 다른 Activity가 모두 종료됩니다

실행하려는 Activity가 현재 스택 맨 위에 있으면 ( Top Activity일 경우 )다시 실행하지 않습니다
즉, onCreate로 화면을 다시 그리는 것이 아니라 onNewIntent로 데이터만 갱신한다고 하네요 🤯
fun newIntent(
context: Context,
): Intent =
Intent(context, MainActivity2::class.java).apply {
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP)
}
위처럼 Intent를 만들고 버튼 클릭 시 Top Activity를 다시 startActivity()로 호출하도록 해 보았습니다
실제로 실행해 보면 onPause() -> onNewIntent() -> onResume() 순서로 함수를 호출하네요

아직은 task를 관리할 정도로 무거운 프로젝트를 해 보지 않아서 와닿는 내용은 아니었지만...
오늘 공부한 내용을 앞으로 개발하면서 응용해 볼 수 있었으면 좋겠네요 🤯🥲