Intent flag를 언제 사용하는가?
안드로이드에서 Activity를 호출하다보면 발생하는 Activity의 중복문제나 흐름을 제어해주고 싶을 때 Flag를 사용합니다.
Task
Task는 Stack 구조로 되어있으며 애플리케이션에서 Activity들을 보관하고 관리합니다.
Flag를 사용하는 2가지 방법
1. Manifest에서 Flag 사용
<activity android:launchMode="사용하고자 하는 Flag"/>
-> launchMode 속성 4가지
standard
이 속성은 별도의 Task를 생성하지 않고 해당 Task에 계속 쌓아나갑니다. Default값은 이 standrd 입니다.
singleTop
이 Flag를 Activity에 설정하면 Task의 Top에 생성하려는 Activity가 존재하는 경우 새로운 Activity를 Top에 올리지않고 기존의 Activity를 재사용합니다.
-> 여기서 재사용이란 Activity가 재사용되서 활성화가 될때 Activity의 Instance가 생성되는 것이 아니라 단지 하나의 B Instance가 onPause() -> onNewIntent() -> onResume() 생명주기만을 반복하는 것을 의미합니다.
singleTask
RootActivity로만 존재하며 하나의 인스턴스만 생성 가능합니다.(다른 Task에서도 동일한 Activity 실행 불가) but, 다른 액티비티 실행시 동일 Task내에서 실행 가능합니다.
singleInstance
루트 액티비티로만 존재하며 하나의 인스턴스만 생성가능하고 태스크내에 해당 액티비티 하나만 속할 수 있어 다른 액티비티를 실행시키면 새로운 Task가 생성되어 (FLAG_ACTIVITY_NEW_TASK와 동일) 그 Task내에 포함됩니다.
소스코드 Flag 제어
Intent.addFlags() : 새로운 flag를 기존 flag에 붙임
Intent.setFlags() : 오래된 flag 전체를 대체
FLAG_ACTIVITY_BROUGHT_TO_FRONT
시스템 디폴트값, 같은 Task에 Activity가 있을 경우에 Activity 실행모드가 singleTask이면 자동으로 설정됨
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
테스크가 리셋될 때 플래그가 사용된 액티비티부터 위의 액티비티가 모두 삭제됩니다.
예) ABCD -> B call - > AB
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
시스템에 의해 홈에서 사용자에 의해 백그라운드에 있던 태스크가 포그라운드로 전환될때에 항상 붙게 됩니다.
FLAG_ACTIVITY_CLEAR_TOP
호출하는 액티비티가 스택에 존재할 경우에, 해당 액티비티를 최상위로 올리면서, 그 위에 존재하던 액티비티들은 모두 삭제를 하는 플래그
예를 들어 ABCDE가 존재하는 상태에서 C를 호출하게 되면 ABC만 남게 됩니다.
cf) onCreate()가 아닌 재사용만 하고 싶을 경우, FLAG_ACTIVITY_SINGLE_TOP 속성과 같이 사용하면 됨
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
실행되는 액티비티들은 최근 실행목록에 표시가 되게 됩니다. 그러나 이러한 표시를 하지 않길 원하는 액티비티가 존재할 경우에 해당 플래그를 넣어주게 되면, 최근 실행목록에 표시가 되지 않게 됩니다.
FLAG_ACTIVITY_FORWARD_RESULT
startActivityForResult를 이용하여서 Activity를 호출할 경우에, 호출하는 쪽이 아닌 한번 더 거쳐서 Result를 받고 싶을 경우가 있습니다.
이러한 경우에 사용하면 되며, A->B->C 일 경우에 C에서 setResult를 설정하여주고, B에서 finish를 하게 되면 A에서는 C의 값을 받을수 있습니다.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
시스템에 의해서 설정되는 Flag, 최근 실행목록에서 실행되게 되면 자동으로 설정됨
FLAG_ACTIVITY_MULTIPLE_TASK
FLAG_ACTIVITY_NEW_TASK와 함께 사용하여야 하며 혼자만 사용할 경우 아무 소용이 없습니다.
두개의 플래그를 동시에 사용할 경우 새로운 태스크는 재활용되지 않고 무조건 새로 생성되며 피호출되는 엑티비티는 이 새로운 태스트의 최상위 엑티비티가 됩니다.
FLAG_ACTIVITY_NEW_TASK
새로운 테스크를 생성하여 그 테스크안에 액티비티를 추가할때 사용합니다. 단, 기존에 존재하는 테스크들중에 생성하려는 액티비티와 동일한 affinity를 가지고 있는 테스크가 있다면 그곳으로 액티비티가 들어가게 됩니다.
하나의 어플리케이션안에서는 모든 액티비티가 기본 affinity를 가지고 같은 테스크안에서 동작하는 것이 기본적이지만, FLAG_ACTIVITY_MULTIPLE_TASK 플래그와 함께 사용 하지 않을 경우 무조건적으로 테스크가 새로 생성되는것은 아님을 주의하여야 합니다.
Affinity 란?
AndroidManifest에서 <activity>
태그의 taskAffinity 속성을 사용해 개별로 affinity를 지정할 수 있다.
FLAG_ACTIVITY_NEW_TASK Flag를 가진 Intent 객체로부터 호출된 allowTaskReparenting 속성을 True로 가지고 있는 Activity에 한해 Affinity가 동작한다.
하나의 어플리케이션 내에서 하나 이상의 기능을 갖는 어플리케이션이 있을 경우 각 액티비티별로 다른 Affinity를 지정해 관리 할 수 있다.
FLAG_ACTIVITY_NO_ANIMATION
액티비티 전환시 애니메이션을 무시합니다.
FLAG_ACTIVITY_NO_HISTORY
액티비티가 스택에 존재하지 않게 되도록 합니다. 로딩화면등에 이용합니다.
FLAG_ACTIVITY_NO_USER_ACTION
이 플래그가 설정되면 자동적으로 액티미티가 호출될 경우에 자동 호출되는 onUserLeaveHint()가 실행되는 것을 차단합니다.
onUserLeaveHint() 콜백 메서드는 어플리케이션 사용중에 전화가 온다거나 하는 등의 사용자의 액션없이 액티비티가 실행/전환되는 경우에 호출되는 메서드 입니다.
FLAG_ACTIVITY_REORDER_TO_FRONT
이 플래그를 이용하게 되면 호출하려는 Activity가 스택에 존재할 경우에, 최상위로 올려주는 효과를 가지게 됩니다.
예를 들어 ABCDE가 있을 경우 C를 호출하게 되면 ABDEC순서로 정렬이 변경되게 됩니다.
FLAG_ACTIVITY_SINGLE_TOP
호출되는 Activity가 최상위에 존재할 경우에는 해당 Activity를 다시 생성하지 않고, 존재하던 Activity를 다시 사용하게 됩니다.
예를 들면 ABC가 존재하는 경우에 C를 호출하게 되면 기존과 동일하게 ABC가 나오게 됩니다.
onPause() -> onNewIntent() -> onResume()