Android LaunchMode 알아보기

염준우·2022년 11월 1일
0
post-thumbnail

이번에는 많은 개발자들이 처음에는 어려워하는 주제를 들고 와봤다. ( 사실, 내가 제일 어려워했다. )
그리고 이 주제는 되게 많은 회사에서 하나의 면접질문으로 나오기도 한다. 나도 이 질문을 면접에서 정말 많이 들었고, 그 때마다 정확하게 말했는지는 알 수 없다.
그래서 확실하게 알아보고, 이제는 면접에서도 정확하게 말할 수 있도록 확실하게 알아보려고 한다.

android:launchMode

Android Manifest 에는 필요한 activity를 설정할 수 있고, 그 activity 가 실행되는 방법을 정의한다.
manifest에서 activity 태그 내에서 android:launchMode 를 정의하고 그 정의된 값에 맞는 값을 사용하게 된다.

이와 같이 Manifest 에서는 launchMode를 5가지로 분류할 수 있다.
이제는 이 launchMode가 각자 어떤 것을 하는지를 차근차근 알아보도록 하자.
편의를 위해 launchMode.{VALUE} 형식으로 작성하도록 하겠다.

launchMode.Standard

가장 기본적으로 사용되는 기본값이다.
시스템에서 활동이 시작된 작업에 새로운 인스턴스를 만들고, 인텐트를 인스턴스로 라우팅시킨다.
액티비티는 여러번 인스턴스로 만들어질 수 있으며, 각각의 액티비티 인스턴스는 다른 작업에 포함되어 있을수도 있다. 또한 하나의 작업에 여러개의 액티비티 인스턴스가 있을 수 있다.

만약 A -> B -> A -> A 이렇게 액티비티가 변화된다고 가정해보자.
launchMode가 standard 일 때는 내 현재 인텐트가 무엇이던 간에, 항상 필요한 액티비티 인스턴스를 만들고, 그 인스턴스로 변화되게 된다. 물론 백 스택에도 남아있다.

launchMode.SingleTop

현재 만들고 싶은 인스턴스가 최상단에 있다면, 시스템이 새로운 액티비티 인스턴스를 만들지 않고, onNewIntent() 를 호출하여 현재 인스턴스의 인텐트를 바꿔주게 된다.
이런 상황을 제외하고는, standard 와 동일한 역할을 하게 된다

standard와 같은 예시를 들어보겠다.
만약 A -> B -> A -> A 와 같이 액티비티 인스턴스가 생성된다고 가정해보자.
그러면 standard에서는 어떤 상황에서도 새로운 액티비티 인스턴스를 만들고 라우팅을 진행하게 된다.
하지만 SingleTop 에서는 그렇지 않다.
A -> B -> A 까지는 동일하게 진행이 되지만, A 액티비티에서 A 인텐트가 왔을 때, 새로운 인스턴스를 만들지 않고, onNewIntent() 함수를 호출하여 새 액티비티 인스턴스를 만들지 않고, 인텐트를 현재 액티비티 인스턴스로 라우팅해주게 된다.

launchMode.SingleTask

SingleTask 로 설정되어 있는 Activity 가 불리게 되면, 시스템이 그 액티비티로 진행되는 새 작업을 만들고, 그 작업에 루트로 현재 액티비티 인스턴스를 라우팅 해주게 된다. 그러나, 이 SingleTask 로 설정되어 있는 액티비티가 어느 한 프로세스에서라도 동작중이면, 그 액티비티의 onNewIntent가 불리면서 인텐트를 현재 존재하고 있는 인스턴스로 라우팅하게 된다. 그 말은 현재 액티비티의 인스턴스는 한 번에 하나만 존재할 수 있다는 것이다.

예를 들어보겠다.
A -> B -> C 인 상황에서 C 가 SingleTask 라고 가정해보자.
A -> B 까지는 하나의 프로세스에서 동작할 것이다. 그러나 B 액티비티에서 C 인스턴스를 만드려고 한다면, C 인스턴스는 새로운 프로세스에서 동작을 하게 될 것이다. 다시 뒤로 가게 되면 C 프로세스는 사라지고, A -> B 액티피티가 존재하는 프로세스로 돌아오게 된다.
A -> B -> A 의 과정에서는, A -> B 과정까지는 그대로 인텐트 형식으로 액티비티가 생성되지만, A 는 이미 하나의 프로세스에서 동작 중에 있기 때문에, 새로운 작업을 만들지 않고, 존재하고 있는 A 액티비티에 onNewIntent() 함수가 불리게 되면서 선택된 인텐트가 존재하고 있는 A 액티비티로 라우팅되게 된다.

launchMode.SingleInstance

SingleTask와 동일한 동작을 제공하지만, 시스템이 SingleInstance로 설정되어 있는 액티비티의 프로세스는 이 액티비티 인스턴스 외에는 어떠한 다른 활동도 실행하지 않는다는 것이 차이점이다.
이 활동으로 시작된 모든 인스턴스 활동들은 별도의 프로세스를 가지고 실행하게 된다.

여기 A -> B -> A -> A를 가진 함수가 있다.
여기서 A가 SingleInstance라고 가정해보자.
그렇게 되면 A -> B 로 인텐트를 움직일 프로세스를 만들 것이며, B -> A 로 갈 때에도 새로운 프로세스를 생성하게 될 것이다. 그리고 A -> A 로 갈 때에도 역시나 SingleInstance 형식을 가지고 있기 때문에, 새로운 프로세스로 시작이 될 것이다. 그래서 결국에는 A 인스턴스를 가진 프로세스 태스크는 3개가 존재할 것이다.

launchMode.SingleInstancePerTask

이 launchMode를 설정한 Instance 는 프로세스의 첫 번째 작업으로만 실행이 될 수 있다고 한다.

A -> B -> A 이 상황에서는
A -> B 는 하나의 작업에서 실행이 되지만, B에서 A 에 대한 인스턴스로 활동은 만들 수 있어도, A의 인텐트를 가진 새로운 프로세스를 만들지 않는 한, A의 인텐트를 가진 새로운 인스턴스를 만들 수는 없다.

그래서... 어떤걸 써야 해???


어떻게 사용되는지를 나열해 봤다.
그리고 구글에서 이렇게 말하기도 했다.
다른 모드인 singleTask, singleInstance, singleInstancePerTask는 대부분의 애플리케이션에 적합하지 않습니다.
보통 사용자들이 사용하기에는 standard 나 singleTop 을 추천한다고 한다.
하지만, 특정 상황에서 singleInstance나 SingleTask 도 사용성에 맞게 사용한다면, 충분히 사용할 수 있는 옵션이니 참고 바란다.

참조: Android Developers

그리고 마지막으로, 제가 아는 것이 이론적으로 확실하지 않을 수 있습니다.
혹시라도 의문점이 있거나, 틀렸다라고 생각되는 부분이 있으면 댓글에다가 편하게 작성부탁드립니다.

profile
항상 새로움을 추구하는 안드로이드 개발자입니다! 🏆

0개의 댓글