이번 포스팅은 Intent FLAG에 대하여 알아보도록 하겠습니다.
Android 플랫폼에서 Activity 는 또 다른 Activity 를 시작할 수 있고, 각각의 Activity 는 차곡 차곡 Task 라고 불리우는 Activity Stack 에 쌓이게 됩니다. 사용자는 뒤로가기를 통해 현재 화면상에 보이는 Activity 를 종료시키고, 바로 직전에 사용된 Activity로 돌아갈 수 있습니다.
구글에서는 Activity를 호출할 때 사용되는 Intent 에 적절한 플래그 값을 설정해서 Activity Stack 을 제어할 수 있는 방법을 제공해 줍니다. 이 플래그들은 FLAG_ACTIVITY 라는 접두어를 갖고 있는데, 개인적으로 가장 요긴하게 사용하고 있는 FLAG_ACTIVITY 네 가지를 소개해 봅니다.
# FLAG_ACTIVITY_SINGLE_TOP
우선 간단하게 그림으로 표현해 보았습니다.
A 와 B 두 가지 Activity가 있습니다. A라는 Activity는 B Activity를 호출하고, B라는 Activity는 다시 자기 자신인 B Activity를 호출하는 경우라고 가정해 보겠습니다. (A->B->B)
A A->B A->B->B
- 호출하는 B Activity가 이미 Task 의 가장 앞에 위치하는 경우, 또 하나의 B Activity를 생성하지 않습니다.
- 기존에 존재하는 B Activity가 재활용이됩니다.
- B Activity가 재활용된다는 것을 개발자가 알아채고 새롭게 전달되는 Intent를 사용할 수 있도록 합니다.
(B Activity 의 onPause() / onNewIntent() / onResume() override 메소드가 순차적으로 호출이 됩니다.)
- 동일한 Activity 를 여러 번 생성하는 것은 메모리 사용량과 Activity 시작 속도 모두에 좋지 않습니다. 이런 경우 FLAG_ACTIVITY_SINGLE_TOP를 적절하게 활용하면 제법 큰 효과를 볼 수 있습니다.
# FLAG_ACTIVITY_NO_HISTORY
우선 간단하게 그림으로 표현해 보았습니다.
A 와 B 두 가지 Activity 가 있습니다. A라는 Activity는 B를 B라는 Activity는 A를 호출한 후에 (A->B->A) 사용자가 뒤로 가기를 하는 경우를 가정해 보겠습니다.
<일반적인 경우> < FLAG_ACTIVITY_NO_HISTORY 적용>
|
|
|
|
|
|
|
|
|
A |
|
|
|
|
|
B |
B |
|
|
B(흔적X) |
A |
A |
A |
A |
|
A |
A |
A |
A A->B A->B->A A A->B A->B->A
- FLAG_ACTIVITY_NO_HISTORY 로 설정된 Intent로 시작된 Activity B는 Task에 그 흔적을 남기지 않게 됩니다.
- B Activity에서 또 다른 A Activity를 호출한 후, 뒤로 가기를 누르면 일반적인 경우 이전에 실행되었던 B Activity가 나타나지만, FLAG_ACTIVITY_NO_HISTORY를 사용하는 경우 맨 처음에 실행되었던 A Activity가 화면에 표시됩니다.
- FLAG_ACTIVITY_NO_HISTORY 를 사용하게 되면 Task에 해당 Intent의 정보가 기록되지 않기 때문에, A->B 인 상황에서 Home 버튼 등을 눌러 다른 Task로 전환된 후, 다시 본 Task로 돌아오게 되면, A Activity가 화면에 표시되는 점은 주의해야 합니다.
- 또한, B Activity 의 onDestroy()가 호출되는 시점이 조금 애매합니다. 일반적인 예상과는 달리, B Activity에서 또 다른 A Activity 를 호출하는 세 번째 단계에서는 onStop() 까지만 호출되고, 이 후에 새롭게 호출된 A Activity 가 뒤로 가기 등 Stack에서 사라지는 순간에서야 onDestroy() 가 호출됩니다.
- FLAG_ACTIVITY_NO_HISTORY 는 여러모로 쓸모가 있는데, 특히 특정한 이벤트 알람 등을 위해 Dialog 형태로 화면에 표시되는 Activity에 적용하기에 편리합니다. (대개의 경우 팝업은 해당 시점에 한 번만 보여주면 되니까.)
#FLAG_ACTIVITY_REORDER_TO_FRONT와 FLAG_ACTIVITY_CLEAR_TOP
우선 간략하게 그림으로 살펴 보겠습니다.
A Activity 에서 B Activity를 그리고 B에서 A를 호출하는 상황을 가정해보았습니다. (A->B->A)
< 일반적인 경우> <FLAG_ACTIVITY_REORDER_TO_FRONT와 FLAG_ACTIVITY_CLEAR_TOP>
A A->B A->B->A A A->B (순서 변환) (A를 최상단)
- FLAG_ACTIVITY_REORDER_TO_FRONT 는 매우 특이하게도 Task의 순서 자체를 뒤바꿔 줍니다.
- 호출하는 Activity가 이미 Task 상에 존재하는 경우 해당 Activity를 새롭게 생성하는 대신, 아래쪽에 위치한 Activity의 순서를 Task의 가장 위로 끌어올려줍니다.
- A->B->A 의 순서로 Activity 호출이 일어날 때, 새로운 A Activity가 생성되는 대신 아래쪽에 위치한 A Activity가 위로 올라와 최종적으로 B->A의 형태로 Task 가 구성되게 됩니다.
- 어떤 Activity에서 특정 Activity로 점프하는 형식의 Flow를 구성해야하는 경우 요긴하게 사용될 수도 있지만, Task의 순서를 뒤섞는다는 점에서 사용에 주의를 기울일 필요가 있습니다. (아무 생각없이 남발하게 되면 뒤로 가기 시 엉뚱한 Activity 가 표시되어 사용자들이 굉장히 혼란스러워하는 경우가 있습니다.)
- FLAG_ACTIVITY_CLEAR_TOP 플래그가 사용되는 경우 호출하는 Activity가 이미 Task 상에 존재하는 경우, 해당 Activity 위에 존재하는 다른 Activity 를 모두 종료시켜 줍니다.
- A->B->A 로 호출이 일어나는 경우, B Activity 가 종료되고, A Activity 만 Task에 남게 됩니다.
(A->B->C->A 인 경우에도 마찬가지로 B와 C 가 종료되고 A 만 남게 됩니다.)
[출처] 안드로이드 알아두면 요긴한 FLAG_ACTIVITY 네 가지