[코딩] 안드로이드 유용한 Activity Flag들 안드로이드

일반적인 경우, 안드로이드 용 어플리케이션을 작성하게 되면 여러가지 Activity 들을 생성하게 됩니다. 이때, 가장 골치가 아픈 일 중 하나는 바로 Activity 와 Activity 간의 Flow 를 설계하고 이를 적절하게 구현하는 일입니다. (특히 안드로이드를 사용해보지도 않은 UX 팀과 함께 일하게 되는 경우라면 더욱 그러합니다...)

 기본적으로 안드로이드 플랫폼 상에서 Activity 는 또 다른 Activity 를 시작할 수 있고, 각각의 Activity 는 차곡 차곡 Task 라고 불리우는 Activity Stack 에 쌓이게 됩니다. 사용자는 일반적으로 Back 버튼을 이용해서 현재 화면상에 보이는 Activity 를 종료 시키고, 바로 직전에 사용된 Activity 로 돌아갈 수 있습니다. 안드로이드 펍의 회색님의 말을 빌리자면, 인터넷 브라우저를 통해 웹페이지를 검색하는 것과 유사한 방식입니다. 

 하지만 이러한 방법만으로는 효과적인 UX Flow 를 구축하는데 어려움이있습니다. 다행히, 구글에서는 Activity 를 호출할 때 사용되는 Intent 에 적절한 플래그 값을 설정해서 Activity Stack 을 제어할 수 있는 방법을 제공해 줍니다. 이 플래그들은  FLAG_ACTIVITY 라는 접두어를 갖고 있는데, 종류가 다양해 헷갈리는 수도 있는데, 개인적으로 제가 가장 요긴하게 사용하고 있는 FLAG_ACTIVITY 네 가지를 소개해 봅니다. 

 먼저 FLAG_ACTIVITY_SINGLE_TOP 입니다. 우선 간단하게 그림으로 표현해 보았습니다. A 와 B  두 가지 Activity 가 있는 데, A 라는 Activity 는 B 를 B 라는 Activity 는 다시 자기 자신인 B 를 호출 하는 경우라고 가정해 보겠습니다. 
< FLAG_ACTIVITY_SINGLE_TOP >

 호출하는 Activity B 가 이미 Task 의 가장 앞에 위치하는 경우, 또 하나의 B 를 생성하는 대신, 기존에 존재하는 B Activity 가 재활용됩니다. 이 때 B 가 재활용된다는 것을 개발자가 알아채고 새롭게 전달되는 Intent 를 사용할 수 있도록 B Activity 의 onPause() / onNewIntent() / onResume() 가 순차적으로 호출됩니다. 별 생각없이 동일한 Activity 를 여러번 생성하는 것은 메모리 사용량과 Activity 시작 속도 양쪽 모두에 악영향을 끼칠 수 있습니다. (특히 이미지가 덕지덕지 붙어 있는 Activity 라면). 이런 경우 FLAG_ACTIVITY_SINGLE_TOP 를 적절하게 활용하면 제법 큰 효과를 볼 수 있습니다.

 두 번째는, FLAG_ACTIVITY_NO_HISTORY 플래그입니다. 우선 간단하게 그림으로 표현해 보았습니다. A 와 B  두 가지 Activity 가 있는 데, A 라는 Activity 는 B 를 B 라는 Activity 는 A 를 호출한 후 에 (A->B->A) 사용자가 Back 키를 누르는 경우를 가정해 보겠습니다.
<FLAG_ACTIVITY_NO_HISTORY>

 말 그대로, FLAG_ACTIVITY_NO_HISTORY 로 설정된 Intent 로 시작된 Activity B 는 Task 에 그 흔적을 남기지 않게 됩니다. B 에서 또다른 A 를 시작한 후, Back 을 누르면 일반적인 경우 이전에 실행되었던 B 가 나타나지만, NO_HISTORY 를 사용하는 경우 맨 처음에 실행 되었던 A 가 화면에 표시됩니다. 몇 가지 주의할 점이 있습니다. 우선 NO_HISTORY 를 사용하게 되면 Task 에 해당 Intent 의 정보가 기록되지 않기 때문에, A->B 인 상황 (그림에서 두 번째 단계...) 에서 홈키등을 눌러 다른 Task 로 전환된 후, 다시 본 Task 로 돌아오게 되면, A Activity 가 화면에 표시됩니다. 또한, B Activity 의 onDestroy() 가 호출되는 시점이 조금 애매합니다.일반적인 예상과는 달리, B 에서 또다른 A Activity 를 호출하는 세 번째 단계에서는 onStop 까지만 호출되고, 이 후에 새롭게 호출된 A Activity 가 사라지는 순간 (네 번째 단계) 에서야 onDestroy() 가 호출 됩니다.

 FLAG_ACTIVITY_NO_HISTORY 는 여러가지로 쓸모가 있는데, 특히 특정한 이벤트에 대한 알람등을 위해 다이얼로그 형태로 화면에 표시되는 Activity 들에 적용하기에 편리합니다. (대게의 경우 팝업은 해당 시점에 한번만 보여주면 되니까.)

 다음으로 굉장히 유용한 플래그 두 가지를 동시에 설명해보고자 합니다. FLAG_ACTIVITY_REORDER_TO_FRONT 와 FLAG_ACTIVITY_CLEAR_TOP 플래그입니다. 우선 간략하게 그림으로 살펴 보겠습니다. A Activity 에서 B Activity 를 그리고 B 에서 A 를 호출하는 상황을 가정해보았습니다. (A->B->A)


 FLAG_ACTIVITY_REORDER_TO_FRONT 는 매우 특이하게도 Task 의 순서 자체를 뒤바꿔 줍니다. 이 플래그를 사용하면, 런치하고자 하는 Activity 가 이미 Task 상에 존재하는 경우 해당 Activity 를 새롭게 생성하는 대신, 아래쪽에 위치한 Activity 의 순서를 Task 의 가장 위로 끌어올려줍니다. 따라서 A->B->A 의 순서로 Activity 호출이 일어날때, 새로운 A 가 생성되는 대신 아래쪽에 위치한 A 가 위로 올라와 최종적으로 B->A 의 형태로 Task 가 구성되게 됩니다. 어떤 Activity 에서 특정 Activity 로 점프하는 형식의 Flow 를 구성해야하는 경우 요긴하게 사용될 수도 있지만, Task 의 순서를 뒤섞는 다는 점에서 사용에 주의를 기울일 필요가 있습니다.  (별 생각없이 남발하게 되면 Back 키가를 누를 때 엉뚱한 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 를 호출할 때 굉장히 유용하게 사용될 수 있습니다. 즉 하나의 어플리케이션이 하나 혹은 두 가지의 주요한 Activity 와 그 외 특정 값을 선택하는등 단순한 일을 수행하기 위한 여러 개의 Sub-Activity 로 구성되어 있다면, 주요 Activity 를 호출하는데 이 Flag 를 사용함으로서 어플리케이션의 홈버튼등을 손쉽게 구현할 수 있습니다. 또 이 Flag 는 FLAG_ACTIVITY_REORDER_TO_FRONT 와는 달린 Task 의 순서를 뒤섞지 않음으로 사용자에게도 큰 혼란을 주지 않습니다. (사용을 적극 권장합니다.)

 한 가지 주의해야할 점은 A->B->A 형태로 Activity 를 호출 하고자 할 때, 단순히 FLAG_ACTIVITY_CLEAR_TOP 만을 사용하게 되면, 기존에 생성되었던 A Activity 가 종료된 후 (onDestroy() 가 호출됨) 새롭게 A 가 생성 (onCreate()) 됩니다. 만일 기존에 사용된 A Activity 가 계속 사용되기를 원한다면, SINGLE_TOP 플래그와 함께 사용해야 합니다.

 휴... 생각보다 내용이 길어졌네요. 대부분 SDK 문서를 읽어보면 잘 나와있는 내용이라 새로운 내용은 없습니다만... 문서 읽기를 게을리한 덕분에 한창을 고생했던 기억이 떠올라 (특히 CLEAR_TOP) 유용하게 사용한 Flag 를 정리하는 겸 작성해 보았습니다~

덧글

  • Auss 2010/06/21 18:59 # 답글

    헉헉. 안드로이드는 아직도 많이 어려운듯 싶습니다;
  • 마틴 2010/06/30 09:40 # 삭제 답글

    좋은 내용의 강좌 잘 보았습니다. 큰 도움 되었습니다. 고맙습니다.
  • 까막눈 2010/11/03 11:24 # 삭제 답글

    SDK에 나와있다고 해도 영어가 안되서 이런 글들이 감사할 뿐입니다. (__)
  • 이삽질선생 2010/12/11 14:45 # 삭제 답글

    좋은 정보 정말 감사합니다^^
    history back 처리를 하다 자꾸 예전 뷰페이지가 남아서 많이 고민했었는데
    Flag 값에 문제였습니다.. ㅎㅎㅎ
    이걸보고 해결했네요^^
    정말 감사합니다..
    혹시 안드로이드 아직 초보 분들은 FLAG_ACTIVITY_SINGLE_TOP 잘 사용 하셔야 할꺼 같아요,...
    뷰페이지가 계속 남아있게 만드네요^^ ..
  • 2011/03/23 16:46 # 삭제 답글 비공개

    비공개 덧글입니다.
  • 캠블 2011/06/03 09:01 # 삭제 답글

    안드로이드를 사용해보지도 않은 UX 팀.. 생각만 해도 피곤하군요.

    잘 보고 갑니다.^^
  • 멋쟁이 2011/08/02 07:49 # 삭제 답글

    좋은글 감사합니다
    잘정리된 글 덕분에 이해하는데 큰 도움이 되었습니다
    감사합니다
  • 주노 2011/09/21 11:41 # 삭제 답글

    와! 제가 부족해서 이해안되는 부분을 제외하고는 정말 쉽게 설명 해주셨네요!! 진심으로 감사드립니다. ^^
  • 프로그래머 2011/11/07 23:56 # 삭제 답글

    잘 보고 갔습니다 ^^
  • 안드로이드초보 2011/12/09 14:37 # 삭제 답글

    음.... FLAG_ACTIVITY_SINGLE_TOP
    이것만 잘 사용해도 많은 도움이 될 거 같네요
    좋은 정보 감사합니다!!
  • ㅇㅊㅎ 2012/01/31 20:11 # 삭제 답글

    감사합니다. ^^ 많은 도움 되었습니다.
  • seso 2012/02/05 07:33 # 삭제 답글

    이 글 덕분에 고민하던 문제를 해결했네요, 감사드립니다^^
  • bluepoet 2012/02/16 16:31 # 삭제 답글

    그림으로 보니까 이해가 더욱 잘되네요.

    좋은 내용 잘 보았습니다.

    감사드려요^^
  • 하라붐 2012/03/02 19:15 # 삭제 답글

    정리가 알기쉽게 잘되어있네요 덕분에 좋은 정보 얻고갑니다.
  • 호너스 2013/11/23 15:59 # 삭제 답글

    정말정말잘읽었습니다~ 책보다 더 잘 설명이 되어있네요!!!!
댓글 입력 영역



surprisen85