이번에는 많은 개발자들이 처음에는 어려워하는 주제를 들고 와봤다. ( 사실, 내가 제일 어려워했다. )
그리고 이 주제는 되게 많은 회사에서 하나의 면접질문으로 나오기도 한다. 나도 이 질문을 면접에서 정말 많이 들었고, 그 때마다 정확하게 말했는지는 알 수 없다.
그래서 확실하게 알아보고, 이제는 면접에서도 정확하게 말할 수 있도록 확실하게 알아보려고 한다.
Android Manifest 에는 필요한 activity를 설정할 수 있고, 그 activity 가 실행되는 방법을 정의한다.
manifest에서 activity 태그 내에서 android:launchMode 를 정의하고 그 정의된 값에 맞는 값을 사용하게 된다.
이와 같이 Manifest 에서는 launchMode를 5가지로 분류할 수 있다.
이제는 이 launchMode가 각자 어떤 것을 하는지를 차근차근 알아보도록 하자.
편의를 위해 launchMode.{VALUE} 형식으로 작성하도록 하겠다.
가장 기본적으로 사용되는 기본값이다.
시스템에서 활동이 시작된 작업에 새로운 인스턴스를 만들고, 인텐트를 인스턴스로 라우팅시킨다.
액티비티는 여러번 인스턴스로 만들어질 수 있으며, 각각의 액티비티 인스턴스는 다른 작업에 포함되어 있을수도 있다. 또한 하나의 작업에 여러개의 액티비티 인스턴스가 있을 수 있다.
만약 A -> B -> A -> A 이렇게 액티비티가 변화된다고 가정해보자.
launchMode가 standard 일 때는 내 현재 인텐트가 무엇이던 간에, 항상 필요한 액티비티 인스턴스를 만들고, 그 인스턴스로 변화되게 된다. 물론 백 스택에도 남아있다.
현재 만들고 싶은 인스턴스가 최상단에 있다면, 시스템이 새로운 액티비티 인스턴스를 만들지 않고, onNewIntent()
를 호출하여 현재 인스턴스의 인텐트를 바꿔주게 된다.
이런 상황을 제외하고는, standard 와 동일한 역할을 하게 된다
standard와 같은 예시를 들어보겠다.
만약 A -> B -> A -> A 와 같이 액티비티 인스턴스가 생성된다고 가정해보자.
그러면 standard에서는 어떤 상황에서도 새로운 액티비티 인스턴스를 만들고 라우팅을 진행하게 된다.
하지만 SingleTop 에서는 그렇지 않다.
A -> B -> A 까지는 동일하게 진행이 되지만, A 액티비티에서 A 인텐트가 왔을 때, 새로운 인스턴스를 만들지 않고, onNewIntent()
함수를 호출하여 새 액티비티 인스턴스를 만들지 않고, 인텐트를 현재 액티비티 인스턴스로 라우팅해주게 된다.
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 액티비티로 라우팅되게 된다.
SingleTask와 동일한 동작을 제공하지만, 시스템이 SingleInstance로 설정되어 있는 액티비티의 프로세스는 이 액티비티 인스턴스 외에는 어떠한 다른 활동도 실행하지 않는다는 것이 차이점이다.
이 활동으로 시작된 모든 인스턴스 활동들은 별도의 프로세스를 가지고 실행하게 된다.
여기 A -> B -> A -> A를 가진 함수가 있다.
여기서 A가 SingleInstance라고 가정해보자.
그렇게 되면 A -> B 로 인텐트를 움직일 프로세스를 만들 것이며, B -> A 로 갈 때에도 새로운 프로세스를 생성하게 될 것이다. 그리고 A -> A 로 갈 때에도 역시나 SingleInstance 형식을 가지고 있기 때문에, 새로운 프로세스로 시작이 될 것이다. 그래서 결국에는 A 인스턴스를 가진 프로세스 태스크는 3개가 존재할 것이다.
이 launchMode를 설정한 Instance 는 프로세스의 첫 번째 작업으로만 실행이 될 수 있다고 한다.
A -> B -> A 이 상황에서는
A -> B 는 하나의 작업에서 실행이 되지만, B에서 A 에 대한 인스턴스로 활동은 만들 수 있어도, A의 인텐트를 가진 새로운 프로세스를 만들지 않는 한, A의 인텐트를 가진 새로운 인스턴스를 만들 수는 없다.
어떻게 사용되는지를 나열해 봤다.
그리고 구글에서 이렇게 말하기도 했다.
다른 모드인 singleTask
, singleInstance
, singleInstancePerTask
는 대부분의 애플리케이션에 적합하지 않습니다.
보통 사용자들이 사용하기에는 standard 나 singleTop 을 추천한다고 한다.
하지만, 특정 상황에서 singleInstance나 SingleTask 도 사용성에 맞게 사용한다면, 충분히 사용할 수 있는 옵션이니 참고 바란다.
그리고 마지막으로, 제가 아는 것이 이론적으로 확실하지 않을 수 있습니다.
혹시라도 의문점이 있거나, 틀렸다라고 생각되는 부분이 있으면 댓글에다가 편하게 작성부탁드립니다.