출처: http://blog.naver.com/oklmg?Redirect=Log&logNo=70105002506
안드로이드 태스크란? (Android Task, Activity Stack) - Task는 어플리케이션에서 실행되는 액티비티를 보관하고 관리하며 Stack형태의 연속된 Activity로 이루어진다 - 선입후출(First In Last Out)형태로 나중에 적재된 액티비티일 수록 가장 먼저 사용된다 만약 1페이지>2페이지>3페이지 순으로 액티비티를 이동했을때 실행순서대로 Task에 push해 놓았다가 back버튼을 누르면 3페이지>2페이지>1페이지순으로 Task에서 pop시켜 되돌아 간다고 생각하면 된다 - 서로 다른 어플리케이션간의 이동에도 Task를 이용해 사용자 경험(UX)를 유지시켜 준다 - 최초적재 액티비티는 Root Activity 라고 하며 어플리케이션 런처로부터 시작된다 - 마지막으로 적재되는 액티비티는 Top Activity 라고 하며 현재 화면에 활성화 되어있는 액티비티를 말한다 - Task내에는 서로 다른 어플리케이션의 액티비티들이 포함될 수 있어 어플리케이션에 경계없이 하나의 어플리케이션인것 처럼 보이게 해준다 - Task의 Stack내에 존재하는 액티비티들은 모두 묶여서 background와 foreground로 함께 이동한다 홈버튼 클릭(task interrupt => background 이동), 홈버튼 롱클릭(recent task => foreground 이동) - Flag를 사용하여 Task내 액티비티의 흐름을 제어할 수 있다. 어피니티란? (Android Affinity) - 어플리케이션 내의 액티비티들은 하나의 어피니티를(affinity:친화력) 가지고 있다 - AndroidManifest 에서 <activity> 요소의 taskAffinity 속성을 사용해 개별 affinity가 지정 가능하다 - FLAG_ACTIVITY_NEW_TASK 플래그를 가진 인텐트 객체로 부터 호출된 allowTaskReparenting 속성을 True로 가지고 있는 액티비티에 한해 affinity가 동작한다 - 위 조건이 만족한 상황에서 시작된 액티비티는 자신과 동일한 어피니티를 갖는 태스크가 있을경우 해당 태스크로 이동한다 - 즉, [b]어피니티를 가진 A액티비티가 호출되어 해당 태스크에 속해있을때 [b]어피니티를 가진 태스크가 호출되면 A액티비티는 [b]어피니티를 가진 태스크로 이동한다 - 어피니티에 의해 태스크가 이동된 후에 back버튼으로 반환시 원래 해당하던 태스크로 돌아간다 - 하나의 어플리케이션내에서 하나 이상의 기능을 갖는 어플리케이션이 존재할경우 각 액티비티별로 다른 어피니티를 지정해 관리할 수 있다 플래그란? (Android Flag) - AndroidManifest 에서 플래그를 사용할때에는 <activity> 요소의 launchMode 속성을 사용하며 launchMode에서 사용가능한 속성은 다음과 같이 4가지만 가능하다 standard: 스택중 어느곳에나 위치 가능하며 여러개의 인스턴스가 생성가능하다 singleTop: 스택중 어느곳에나 위치 가능하며 여러개의 인스턴스가 생성가능하고 호출한 activity와 현재 최상위 activity가(top activity) 동일한 경우 최상위 activity가 재사용 된다(기존 최상위 activity는 pop) singleTask: 루트 액티비티로만 존재하며 하나의 인스턴스만 생성가능하다(타 task에서 동일 activity 사용불가) 다른 액티비티 실행시 동일 Task내에서 실행이 가능하다
singleInstance: 루트 액티비티로만 존재하며 하나의 인스턴스만 생성가능하고 태스크내에 해당 액티비티 하나만 속할 수 있어 다른 액티비티를 실행시키면 새로운 Task가 생성되어 (FLAG_ACTIVITY_NEW_TASK와 동일) 그 Task내에 포함된다 - 소스코드에서 플래그를 사용하고 싶을때에는 Intent에 addFlags() 또는 setFlags() 메소드를 사용한다 FLAG_ACTIVITY_NEW_TASK: 동일 affinity의 task가 있으면 그곳에 실행되고 아니면 새로운 task를 실행 FLAG_ACTIVITY_SINGLE_TOP: 상단 singleTop과 같으며, 실행시 재사용 액티비티의 실행은 onPause(), onNewIntent(), onResume() 순으로 호출된다 ☞ [B]를 single top설정: [A][B] 상태에서 [B] 호출시 => [A][재사용된B] ☞ [B]를 single top설정: [B][A] 상태에서 [B] 호출시 => [B][A][B] FLAG_ACTIVITY_NO_HISTORY: 해당 액티비티는 재활성화시(back키를 눌러 다시 활성화될때) pop 된다 ☞ [B]를 no history설정: [A][B][A] 상태에서 back키 사용시 [A]가 pop 되고 [B] 역시 no history에 의해 pop => [A] FLAG_ACTIVITY_REORDER_TO_FRONT: activity 호출시 이미 같은 activity가 task내에 있으면 같은 activity는 pop 시키고 해당 activity가 push 된다 ☞ [A]를 reorder to front설정: [A][B] 상태에서 [A] 호출시 같은 activity인 [A]가 pop되고 => [B][A] FLAG_ACTIVITY_CLEAR_TOP: 해당 task에 있는 모든 activity를 pop 시키고 해당 activity가 root activity로 task에 push된다 ☞ [A]를 clear top설정: [A][B] 상태에서 [A] 호출시 모두 pop되고 => [A] 단, 해당 플래그는 액티비티를 모두 onDestroy() 시킨 후 새롭게 onCreate() 시키기 때문에 [A]를 유지하려면 FLAG_ACTIVITY_SINGLE_TOP 플래그와 함께 사용하면 된다 http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_BROUGHT_TO_FRONT Clear Task - Task를 오랫동안 사용하지 않고 방치해 두면 시스템은 Root Activity를 제외한 모든 액티비티를 Clear 시킨다 - 이러한 동작은 Activity의 속성을 수정하여 제어할 수 있다 alwaysRetainTaskState: Task의 Root Activity에 true로 설정되어 있다면 상단에 언급되었던 동작은 발생하지 않으며 Task는 오랜 시간 이후에도 Stack에 있는 모든 Activity를 유지한다 clearTaskOnLaunch: 이 속성이 true로 설정되어 있으면 alwaysRetainTaskState 와 정반대로 사용자가 Task를 떠났다가 다시 돌아올 때마다 항상 Stack은 Root Activity로 정리된다 finishOnTaskLaunch: 이 속성은 clearTaskOnLaunch와 유사하지만 전체 Task가 아닌 단일 Activity에서 동작한다 그리고 그것은 Root Activity를 포함한 어떤 Activity가 사라지는 원인이 될 수도 있다 true로 설정되어 있을 때, Activity는 현재 Session 동안 Task의 일부만 유지한다 만일 사용자가 해당 Task를 벗어났다가 다시 돌아오면 더이상 존재하지 않는다. |
출처 : [KANDROID]
startActivity()에 파라메터로 전달하여 호출하는것 뿐이다.
이 때 BACK버튼을 누르면 viewer를 시작한 당신의 activity가 다시 보여질 것이다.
이는 사용자로 하여금 street map viewer가 당신의 application의 일부라고 느끼게 한다.
root activity는 task상의 첫번째 activity이고 top activity는 현재 화면에 보여지는 activity이다. activity가 다른 activity를 시작하면
Task는 activity들의 stack이다. 따라서 task내의 activity에 어떤 값을 설정하는 방법은 없다.
A1 -> A2 -> A3 -> A4 -> HOME -> B 1-> B2 -> HOME -> A4 -> BACK -> A3
task와 activity간의 결합과 동작에 대한 제어는 intent object의 flag 파라메터와 minifest의 <activity> element의 몇가지 속성으로 제어가 가능하다.
flag -> FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TOP, FLAG_ACTIVITY_RESET_TASK_IF_NEEDED, FLAG_ACTIVITY_SINGLE_TOP
<activity>'s attributes -> taskAffinity, launchMode, allowTaskReparenting, clearTaskOnLaunch, allowRetainTaskState, finishOnTaskLaunch
Affinityes and new Tasks
FLAG_ACTIVITY_NEW_TASK 적용시
앞서 기술한대로 기본적으로 activity는 startActivity()로 task안에 적재된다. caller와 동일한 stack에 push된다.
allowTaskReparenting 적용시
특정 activity가 allowTaskReparenting속성이 "true"이면, 시작된 task에서 동일한 affinity를 갖는 다른 task가 foreground로 올라올때
travel application : Weather activity, ... -> allowTaskReparenting이 true이고 모두 동일 affinity를 갖는다.
your application : A, B, C, D activity
launch travel application -> (1)start Weather activity -> HOME -> launch your application -> start A activity -> (2)start Weather activity -> HOME -> (3)travel application -> display Weather activity
(1) 시점에서 weather activity는 task1(travel app의 task)에 적재된다.
하나의 패키지(*.apk)에 여러 application이 정의되어 있다면 app단위로 각기 다른 affinity를 부여하는것이 좋다.
Launch Mode
standard, singleTop, singleTask, singleInstance
위 4가지 모드는 4가지 관점에서 다르게 동작한다.
- standard, singleTop모드는 intent가 발생된 task에 push된다.
flag를 FLAG_ACTIVITY_NEW_TASK로 설정해도 호출한 동일한 task내에 push된다.
singleTask및 singleInstance는 task를 정의하여 root activity로 적재되고 다른 task에 적재되지 않는다.
* 다중 instance activity가 가능한가?
- standard, singleTop모드는 여러 task에 소속될수도 있고 한 task에 동일한 activity가 여러 instance가 적재될수도 있다.
singleTask, singleInstance는 task내에서 오로지 한개의 instance만 적재된다.
- singleInstance는 task내에서 오직 하나의 instance만 가능하며, 만일 다른 activity를 시작하면 launchMode에 관계없이 새로운 task가 생성되어
적재된다. standard, singleTask, singleTop은 모두 multi instance가 가능하다. singleTask는 root activity로 생성되며 다른 activity를 task내에
적재가 가능하다. singleTop과 standard모드는 stack내에서 자유롭게 다른 activity를 생성가능하다.
- standard모드는 새로운 instance가 새로운 intent의 응답으로 생성된다. 각 instance는 오직 하나의 intent를 다룬다.
singleTop : target-task의 stack에 top activity로 있다면 그 class의 instance가 intent를 재사용하여 처리한다.
예) A - B - C - D에서 D를 시작하려고 할 때 D가 singleTop이면 A - B - C - D 로된다.
A - B - C - D에서 D를 시작하려고 할 때 D가 standard이면 A - B - C - D - D 로된다.
B가 singleTop이나 standare이면 A - B - C - D - B 가 가능하다.
Clearing the stack
alwaysRetainState 속성
- task의 root activity에 이 속성을 set하면 이 task는 오랜시가이 지나도 생존하게 된다.
clearTaskOnLaunch 속성
- task의 root activity에 이 속성을 set하면 task를 나가고 돌아올때 clear된다.
finishOnTaskLaunch 속성
- clearTaskOnLaunch와 유사하나 이 속성은 하나의 activity에만 유효하다.
root activity를 포함하여 현재 세션인 경우에만 살아있고 task를 떠나면 clear된다.
stack에서 activity를 제거하는 다른 방법이 있다.
intent object의 flag를 FLAG_ACTIVITY_CLEAR_TOP로 하고 이 intent를 처리할 activity가 target task에 이미 instance를 가지고 있다면
상위 activity들이 모두 clear되고 그 activity가 top activity가 된다.
launchMode가 "standard"라면 stack에서 마찬가지로 삭제되고 새로운 activity가 그 intent를 처리할 것이다.
FLAG_ACTIVITY_NEW_TASK와 FLAG_ACTIVITY_CLEAR_TOP이 함께 사용되면 존재하는 activity가 새 task에 생성되어 intent를 처리한다.
Starting task
설정된다. 이런 설정은 icon과 label정보를 가지로 화면에 표시하고 task에 적재하고 적재후 언제든지 다시 돌아올수 있도록 해준다.
filter로 적용해야 한다. 그러지 않으면 activity를 수행후 다른 화면으로 갔다가 다시 돌아올 수 있는 방법이 없게 된다.
FLAG_ACTIVITY_NEW_TASK 는 activity하나가 새로운 task에 시작되고 HOME key를 눌렀을 경우 다시 복귀하기 위해 다른 방법이 있다.
이런 방식으로 외부에서 activity를 invoke할 수 있다면 사용자가 다른 방법으로 그 task를 시작할 수 있음을 유의해야 한다.
이런 경우 그 activity로 복귀하기를 원하지 않는다면 finishOnTaskLaunch를 사용하면 된다.
태스크와 백스택
앱은 보통 여러개의 액티비티로 구성됩니다. 각 액티비티는 특정한 목적을 갖는 화면을 보여주며, 다른 액티비티들을 실행할 수 있습니다.
예를 들어, 이메일앱은 읽지 않은 이메일 목록을 보여주는 액티비티가 있으며, 목록에서 이메일을 선택하면 그 이메일 내용을 보여주는 액티비티도
있습니다.
액티비티는 디바이스에 설치된 다른 앱의 액티비티도 실행할 수 있습니다. 예를 들어, 내 앱에서 이메일 보내기가 되도록 하고 싶다면,
Intent.ACTION_SEND 액션값과 이메일 주소 및 메시지를 담고 있는 인텐트를 만들어서 실행하면 됩니다.
그러면 디바이스에 설치된 모든 앱 중에서 해당 인텐트에 대응되는 즉, 이메일을 비롯한 데이터를 보내는 기능을 수행하는 액티비티가 실행될 것입니다.
만약 그러한 액티비티가 2개 이상이라면 사용자가 선택할 수 있도록 다이얼로그를 띄워 줍니다.
이메일 보내기 작업이 완료되면 이메일 쓰기 액티비티가 종료되면서 내 앱의 액티비티가 다시 resumed 상태가 되는데,
이는 마치 이메일 쓰기 액티비티가 내 앱의 일부인 것처럼 보이게 합니다. 이러한 경우, 비록 액티비티들이 서로 다른 앱에 속해 있긴 하지만
같은 태스크에 있음으로써 사용자에게 자연스러운 사용자 경험(UX)을 제공할 수 있는 것입니다.
태스크는 사용자에 의해 실행된 액티비티들의 모음입니다. 액티비티들은 생성되면서 "백스택"이라 불리는 스택에 쌓이게 됩니다.
디바이스의 홈 화면은 거의 모든 태스크들의 시작점입니다. 사용자가 앱 런처에서 앱 아이콘을 터치하거나, 홈 화면의 바로가기 아이콘을 터치하면,
앱의 태스크가 전면(foreground)으로 나오게 됩니다. 만약 앱을 최근에 실행한 적이 없어서 태스크가 없다면, 새 태스크가 생성되며
앱의 "메인" 액티비티가 실행되고 태스크의 root가 됩니다.
현재 액티비티가 다른 액티비티를 실행하면, 실행된 새 액티비티가 스택의 top에 들어가면서 포커스를 획득하며,
이전 액티비티는 여전히 스택에 들어가 있기는 하지만 stopped 상태가 됩니다. 액티비티가 정지되더라도(stop), 시스템은 액티비티의 사용자 인터페이스(UI)의 현재 상태를 보존하며, 사용자가 뒤로가기 버튼을 눌렀을 때, 현재의 액티비티를 스택에서 꺼내고(popped. 이때 액티비티는 종료됩니다),
이전 액티비티를 resumed 상태로 만듭니다. (정지되기전 UI 상태가 복구됩니다). 스택에 있는 액티비티의 배열은 절대 바뀌지 않습니다.
단지 스택에 넣고(push) 꺼내는(pop) 동작만 있을 뿐입니다.
액티비티가 생성될 때 스택에 넣고, 사용자가 뒤로가기버튼을 눌러서 종료될 때 꺼내는 것입니다.
이러한 백스택의 자료구조를 "후입선출"이라고 표현합니다. 아래의 그림1은 액티비티들이 백스택에 어떻게 들어가고 나오는지를 보여줍니다.
그림 1. 이 그림은 태스크의 새 액티비티가 백스택에 어떻게 추가되는지와, 뒤로 가기버튼을 눌렀을 때 현재 액티비티가 종료되며
이전 액티비티가 다시 resumed 상태가 되는 것을 보여줍니다.
만약 사용자가 계속 뒤로가기버튼을 누른다면, 스택의 top에 있는 액티비티가 제거되면서 이전 액티비티가 resumed 상태로 스택의 top이 될 것이고,
결국은 홈화면으로 빠져나갈 것입니다(또는 해당 태스크가 시작되기 전의 마지막 액티비티가 실행될 것입니다).
태스크의 모든 액티비티가 제거되면, 그 태스크도 없어집니다.
그림 2. 두개의 태스크: 태스크 B는 전면(foreground)에서 사용자와 상호작용을 하지만
태스크 A는 후면(background)에서 다시 resumed 상태가 되기를 기다립니다.
태스크는 사용자가 다른 태스크를 시작하거나, 홈버튼을 눌러서 홈화면으로 전환될 때, "후면(background)"으로 이동합니다.
후면에 있을 때, 태스크의 모든 액티비티들은 stopped 상태가 되지만, 태스크의 백스택은 액티비티들을 잘 유지하며, 그림2에서 보이는 바와 같이
다른 태스크에게 자리를 내주고 포커스만 잃게 되는 것입니다.
태스크는 다시 "전면(foreground)"으로 나설 수 있으며, 사용자는 해당 태스크의 마지막 화면을 볼 수 있습니다.
예를 들어, 현재의 태스크(Task A)가 스택에 3개의 액티비티를 담고 있는데, 사용자가 홈버튼을 눌러 홈화면으로 이동한 후 앱 런처에서 다른 앱을
실행한다고 가정해 봅시다.
홈화면으로 이동할 때, Task A는 후면으로 이동합니다. 그리고 다른 앱을 실행할 때, 시스템은 그 앱의 태스크인 Task B를 시작하는데 그것은 자신의 액티비티들을 담을 스택을 따로 갖습니다. 그 앱에서 사용자가 할 일을 마치고 홈화면으로 돌아갔다가 다시 이전의 앱을 실행하면, Task A가 다시 전면으로 나설 것이며, 스택에 있던 3개의 액티비티는 모두 무사하고, 스택의 top에 있는 액티비티(사용자가 Task A에서 마지막으로 실행한 액티비티)가 다시 resumed 상태로 될 것입니다. 홈화면으로 이동할 때 Task B는 후면으로 이동합니다. 이전 태스크를 다시 전면으로 가져오는 방법은 해당 앱의 아이콘을 클릭하거나, 홈버튼을 길게 누르면 보이는 최근 태스크 목록에서 태스크를 선택하면 됩니다. 이것은 안드로이드 멀티태스킹의 한 예입니다.
메모: 여러개의 태스크가 동시에 후면에 있을 수 있긴 하지만, 메모리가 부족할 경우 시스템이 메모리를 회복하기 위해 후면에 있는
태스크의 액티비티들을 종료할 수도 있습니다. 본 문서에서는 액티비티의 상태를 저장하는 방법에 대해서도 학습할 것입니다.
그림 3. 하나의 액티비티가 여러개의 서로 다른 객체로 생성될 수 있습니다.
백스택의 액티비티들은 절대 재배치되지 않기 때문에, 만약 내 앱에서 특정 액티비티가 여러개의 다른 액티비티로부터 실행될 수 있다면,
그 액티비티는 생성될 때마다 새로운 객체로 스택에 추가될 것입니다(기본적으로는, 스택에 있는 동일한 액티비티의 객체를 재사용하지 않습니다).
위의 그림3에서 보이는 바와 같이 하나의 액티비티가 여러번 객체로 생성될 수 있는 것입니다.
그리고 그림3과 같은 상황에서 사용자가 뒤로가기버튼을 연이어 누른다면, 백스택의 top에 있는 액티비티부터 차례대로 (해당 액티비티의 현재 UI상태가) 화면에 출력될 것입니다.
하지만, 액티비티의 객체가 한번만 생성되고 그것이 재사용되도록 할 수도 있으며, 자세한 내용은 태스크 관리하기 섹션에서 학습하실 수 있습니다.
액티비티와 태스크에 관한 기본적인 동작을 요약하면 아래와 같습니다:
- 액티비티 A가 액티비티 B를 실행하면, 액티비티 A는 stopped 상태가 되지만, 시스템은 (스크롤 위치나 입력 영역에 입력된 문자열 등의) 액티비티 A에 대한 현재 상태를 유지합니다. 그리고 액티비티 B가 전면(foreground)에 있는 상태에서 뒤로가기버튼을 누르면 액티비티 A가 이전 상태를
유지하면서 다시 resumed 상태가 됩니다. - 사용자가 홈 버튼을 눌러서 현재 태스크로부터 빠져나가면, 현재 액티비티는 stopped 상태가 되고 태스크는 후면(background)으로 이동하지만,
시스템은 태스크의 액티비티들에 대한 상태를 유지해 줍니다. 그리고 만약 사용자가 런처에서 해당 앱 아이콘을 눌러 다시 앱을 실행하고자 하면,
해당 태스크가 다시 전면(foreground)으로 나오면서 백스택의 top에 있는 액티비티가 다시 resumed 상태가 됩니다. - 사용자가 뒤로가기버튼을 누르면, 현재 액티비티가 백스택에서 빠지면서 종료되고, 이전 액티비티가 resumed 상태로 변경됩니다.
액티비티가 종료되면, 시스템은 더이상 종료된 액티비티의 상태를 유지해주지 않습니다. - 액티비티는 (어떤 태스크에서건) 여러번 객체로 생성될 수 있습니다.
네비게이션 설계: 안드로이드에서 앱의 네비게이션이 어떻게 동작하는지에 대한 자세한 내용은 안드로이드 디자인 영역의 네비게이션 가이드에서
학습하실 수 있습니다.
액티비티의 상태 저장하기
위에서 학습한 바에 따르면, 시스템은 기본적으로 액티비티가 stopped 상태로 될 때, 그 상태를 유지해줍니다.
이대로라면, 사용자가 뒤로가기버튼을 눌러 이전 액티비티로 이동할 때, 보여지는 상태는 사용자가 그 액티비티에서 벗어날 때의 마지막 상태가 됩니다.
하지만, 액티비티는 사용자의 의도와 상관없이 시스템에 의해 종료 및 재생성 되는 경우가 있기 때문에, 액티비티의 콜백 메소드를 이용하여 상태를
저장해야 합니다.
액티비티가 stopped 상태로 변경되면(새 액티비티를 실행하거나, 태스크가 후면(background)으로 이동하거나 하는 경우), 시스템은 메모리를 확보하기 위해 액티비티를 완전히 종료시켜버릴 수도 있습니다. 이러한 경우, 액티비티의 상태에 대한 정보는 모두 잃게 되지만, 백스택에서도 해당 액티비티가
빠지는 것은 아닙니다. 따라서, 시스템에 의해 종료된 액티비티가 백스택의 top에 오게 되면, (재사용할 액티비티 객체가 종료되었으므로) 액티비티를
다시 생성해야 합니다. 이러한 경우 액티비티의 상태를 복구하기 위해서는, 액티비티의 onSaveInstanceState() 콜백 메소드에서 상태를 저장하도록
구현해야 합니다. 이와 관련하여 더 자세한 내용은 액티비티의 상태 저장하기 문서에서 학습하실 수 있습니다.
태스크 관리하기
위에서 학습한 바와 같이 안드로이드는 기본적으로, 연이어 생성되는 액티비티들을 같은 태스크 내에 그리고 "후입선출" 스택에 집어 넣습니다.
태스크와 백스택을 관리하는 안드로이드의 이러한 방식은 대부분의 앱에서 훌륭하게 작동하며, 보통은 액티비티들이 어떤 태스크에 속하고
어떤 백스택에 들어가 있는지를 신경쓸 필요가 없습니다.
하지만, 내 앱에서는 이러한 안드로이드의 기본 동작과는 다르게 구현하고 싶을 수 있겠죠. 액티비티가 생성될 때 현재 태스크가 아닌 새로운 태스크를
시작하고 싶을 수도 있고, 현재 태스크에 액티비티의 객체가 있다면 액티비티 객체를 새로 생성하지 않고 이미 있는 액티비티 객체를 재사용하고
싶을 수도 있을 것입니다. 또는 사용자가 현재 태스크에서 벗어날 때, root에 있는 액티비티를 제외하고 나머지는 모두 제거하고 싶을 수도
있을 것입니다.
이러한 요구사항들은, 매니페스트 파일의 <activity> 요소에 관련 속성을 추가하거나, 소스코드의 startActivity()에 넘길 인텐트에 플래그를 추가함으로써 구현할 수 있습니다.
<activity> 요소의 주요 속성들:
- taskAffinity
- launchMode
- allowTaskReparenting
- clearTaskOnLaunch
- alwaysRetainTaskState
- finishOnTaskLaunch
인텐트의 주요 플래그들:
- FLAG_ACTIVITY_NEW_TASK
- FLAG_ACTIVITY_CLEAR_TOP
- FLAG_ACTIVITY_SINGLE_TOP
이어지는 섹션에서는, 액티비티들이 어떤 태스크에 속하고 어떤 백스택에 들어가게 될지를 정의하기 위해서, 매니페스트의 속성들 및 인텐트의
플래그들을 사용하는 방법에 대하여 학습할 것입니다.
주의사항: 대부분의 앱에서는 액티비티와 태스크에 대한 기본 동작을 변경할 필요가 없습니다.
만약 변경할 필요가 있다면, 앱이 실행되는 동안의 사용성과 다른 액티비티 및 태스크에서 뒤로 가기버튼을 눌러 돌아오는 동작 등에 대하여
충분히 테스트를 함으로써, 사용자가 기대하는 동작과 어긋나지 않도록 신경을 써야 합니다.
시작(launch) 모드 정의하기
시작 모드는 액티비티의 새 객체가 현재의 태스크에 어떻게 속하게 될지를 결정해 줍니다.
아래와 같이 2가지 방식으로 시작 모드를 지정할 수 있습니다:
메니페스트 파일에 액티비티를 선언할 때, 액티비티 생성시 태스크에 어떻게 속하게 될지를 지정할 수 있습니다.
소스코드에서 startActivity() 호출할 때, 인텐트에 플래그를 추가함으로써 액티비티가 태스크에 어떻게 속하게 될지를 지정할 수 있습니다.
액티비티 A가 액티비티 B를 실행하는 경우에, 액티비티 B는 매니페스트 파일에 속성을 추가함으로써 자신이 현재 태스크에 어떻게 속하게 될지를
지정할 수 있고, 액티비티 A는 액티비티 B를 실행하는 인텐트에 플래그를 추가함으로써 같은 역할을 할 수 있습니다.
이 둘은 모두 액티비티 B와 태스크의 관계를 지정하는 것이며, 액티비티 A의 인텐트 실행이 액티비티 B의 매니페스트 파일 지정보다 우선합니다.
메모: 매니페스트 파일에 지정되는 일부 시작 모드는 인텐트를 통해 구현될 수 없고, 반대로 인텐트 플래그로 지정되는 일부 시작 모드는
매니페스트 파일에 지정될 수 없습니다.
매니페스트 파일 사용하기
매니페스트 파일에 액티비티를 선언할 때, <activity> 요소에 launchMode 속성을 추가함으로써
액티비티가 태스크와 어떤 관계를 맺게 될지를 지정할 수 있습니다.
launchMode 속성은 액티비티가 태스크에 어떤 방식으로 추가될 지를 지정합니다.
아래에 4가지 launchMode 속성값에 대해 간단히 설명하겠습니다:
"standard" (기본값)
시스템은 액티비티를 실행하려고 인텐트를 넘겨주고 있는 그 태스크에서 액티비티의 새 객체를 생성합니다.
액티비티는 여러번 객체를 생성할 수 있고, 각각은 서로 다른 태스크에 들어갈 수도 있으며,
하나의 태스크가 (한 액티비티에 대한) 여러개의 객체를 포함할 수 있습니다.
"singleTop"
어떤 액티비티의 객체가 이미 현재 태스크의 top에 있는데 그 액티비티에 대하여 startActivity()를 호출할 경우,
시스템은 액티비티의 새 객체를 생성하는 대신에 태스크의 top에 있는 액티비티 객체의 onNewIntent()를 호출함으로써 재사용합니다.
위의 standard와 마찬가지로, 액티비티는 여러번 객체를 생성할 수 있고, 각각은 서로 다른 태스크에 들어갈 수도 있으며,
하나의 태스크가 (한 액티비티에 대한) 여러개의 객체를 포함할 수 있습니다.
하지만, 태스크의 top에 하나의 액티비티에 대한 2개의 객체가 들어가는 상황만은 허용하지 않으며, 이미 있는 객체를 재사용하도록 하는 것입니다.
예를 들어, 태스크의 백스택이 A, B, C, D라는 액티비티로 채워져있다고 가정해 봅시다(스택은 A-B-C-D이며, D가 top입니다).
그리고 시스템에게 D를 실행해 달라는 인텐트가 왔다고 합시다. 만약 D의 시작 모드(launchMode)가 "standard"라면, D의 새 객체가 생성되어
백스택에 추가되고 스택은 A-B-C-D-D가 될 것입니다. 하지만 D의 시작 모드가 "singleTop"이라면, 백스택의 top에 이미 D의 객체가 있기 때문에
그 객체가 onNewIntent()를 통해 해당 인텐트를 받을 것이고 스택은 그대로 A-B-C-D가 될 것입니다. 하지만 시작되는 액티비티가 D가 아닌 B라면
시작 모드가 "singleTop"이라 하더라도, 새 객체가 생성되어 백스택에 추가될 것이고 스택은 A-B-C-D-B가 될 것입니다.
메모: 액티비티의 새 객체가 생성되어 태스크에 추가되었을 때, 사용자가 뒤로가기버튼을 누르면 이전 액티비티로 돌아갈 수 있었습니다.
그러나 시작 모드가 "singleTop"이라서 태스크의 top에 있는 액티비티가 재사용된 상황이라면, 사용자가 뒤로가기버튼을 눌렀을 때,
재사용되기 전 상태로 돌아가는 것이 아니라, 현재 액티비티가 종료되고 그 이전의 액티비티가 재시작될 것입니다.
"singleTask"
시스템은 새 태스크를 생성하고, 태스크의 root에 액티비티의 새 객체를 생성합니다.
하지만, 태스크에 이미 해당 액티비티의 객체가 존재한다면, 액티비티의 새 객체를 생성하지 않고 기존 객체의 onNewIntent()를 호출함으로써
재사용합니다. 하나의 액티비티에 대한 객체는 오직 하나만 존재할 수 있습니다.
메모: 비록 액티비티가 새 태스크에 생성되었다 하더라도, 뒤로가기버튼을 누르면 이전 액티비티로 돌아갈 수 있습니다.
역자의 추가글: singleTask에 대한 설명이 오해의 소지가 많아 몇가지 설명을 덧붙입니다.
시스템은 시작 모드가 singleTask인 액티비티를 실행할 때 taskAffinity가 같은 태스크가 있는지를 확인하여,
만약 있다면 그 태스크에 액티비티의 객체를 생성하여 넣으며, 이때의 위치는 태스크의 root가 아니겠죠.
그리고 만약 taskAffinity가 같은 태스크가 없다면, 새 태스크를 생성하고 그 태스크의 root에 액티비티의 새 객체를 생성합니다.
taskAffinity에 대한 자세한 내용은 아래의 친밀도(affinity) 다루기에서 학습하실 수 있습니다.
"singleInstance"
자신이 속한 태스크에 다른 액티비티의 객체들을 들어오지 못하게 한다는 점을 제외하고는 "singleTask"와 비슷합니다.
하나의 액티비티에 대한 객체는 오직 하나이고, 자신이 속한 태스크에는 오직 자신만 있을 뿐입니다.
이 액티비티에서 다른 액티비티를 실행한다면, 실행된 액티비티는 다른 태스크에 속하게 됩니다.
다른 예로, 인터넷 브라우저 앱은 브라우저 액티비티의 시작 모드를singleTask로 지정했기 때문에, 내 앱에서 브라우저를 실행할 때
브라우저 액티비티가 내 앱의 태스크에 들어가지 않습니다. 대신에 새 태스크를 생성하거나, 이미 존재하는 브라우저의 태스크가 후면(background)에
있다면 전면(foreground)으로 가져와서 재사용합니다.
액티비티가 새 태스크에 들어갔건, 기존의 태스크에 들어갔건 상관없이 사용자가 뒤로가기버튼을 누르면 현재 액티비티가 종료되고
이전 액티비티가 실행됩니다. 하지만, 시작 모드가 singleTask인 액티비티를 실행하는데, 그 액티비티는 이미 후면에 있는 태스크에 존재하고
그 태스크에는 다른 액티비티도 있는 경우, 시스템은 후면에 있던 태스크를 통째로 전면으로 가져옵니다.
이 때, 현재의 백스택의 top에다가, 후면에서 가져온 태스크의 액티비티들을 모두 집어넣습니다.
아래의 그림4가 이 과정을 보여줍니다.
그림 4. 시작 모드가 "singleTask"인 액티비티를 백스택에 추가하는 모습을 보여줍니다.
만약 액티비티가 후면에 있는 다른 태스크에 이미 존재한다면, 그 태스크가 통째로 현재의 태스크의 top으로 옮겨오게 됩니다.
매니페스트 파일에 시작 모드를 설정하는 방법에 대한 더 자세한 내용은,<activity>의 android:launchMode에서 학습하실 수 있습니다.
메모: 매니페스트 파일에서 지정한 launchMode는, 액티비티를 실행할 때 넘겨주는 인텐트에 포함된 플래그값으로 덮어씌워질 수 있습니다.
다시 말해서, 인텐트에 포함된 (시작 모드에 대한) 플래그값이 매니페스트 파일에 지정된 시작 모드보다 우선합니다.
인텐트의 플래그 사용하기
액티비티를 실행할 때, startActivity()에 넘겨주는 인텐트에 플래그를 설정함으로써 액티비티의 시작 모드를 바꿀 수 있습니다.
그 플래그값들은 아래와 같습니다:
FLAG_ACTIVITY_NEW_TASK
실행하려는 액티비티의 객체가 존재하지 않으면 새 태스크의 root에 액티비티의 새 객체가 들어갑니다.
하지만 후면(background)에 이미 그 액티비티를 담고 있는 태스크가 있다면, 전면(foreground)으로 가져와서 마지막 상태를 복구하고
인텐트를 onNewIntent()에 넘겨줍니다. 하지만 후면에 있던 태스크의 top에 있던 액티비티가 실행되기 때문에, 실행하고자 했던 액티비티와
실행된 액티비티가 다를 수도 있습니다. 따라서 대부분의 경우 FLAG_ACTIVITY_CLEAR_TOP과 함께 사용합니다.
이것(FLAG_ACTIVITY_NEW_TASK + FLAG_ACTIVITY_CLEAR_TOP)은 위에서 학습한 "singleTask"의 역할과 같습니다.
FLAG_ACTIVITY_SINGLE_TOP
현재 실행중인 액티비티(현재 태스크의 top에 있는)에서 다시 동일한 액티비티를 실행하려고 하는 경우,
새 객체를 생성하는 대신 현재 액티비티의 onNewIntent()를 호출함으로써 액티비티를 재사용합니다.
이것은 위에서 학습한 "singleTop"의 역할과 같습니다.
FLAG_ACTIVITY_CLEAR_TOP
만약 실행하려고 하는 액티비티의 객체가 이미 현재 태스크에 존재한다면, 새 객체를 생성하는 대신, 그 액티비티 객체의 위에 있는
다른 액티비티들을 모두 제거하여 그 액티비티가 태스크의 top이 되도록 합니다. 이것과 역할이 같은 launchMode값은 없습니다.
다시 말하지만, FLAG_ACTIVITY_CLEAR_TOP은 대부분의 경우 FLAG_ACTIVITY_NEW_TASK와 함께 사용됩니다.
이 경우, 실행하려고 하는 액티비티가 후면(background)에 있는 태스크에 존재한다면, 그 태스크를 전면(foreground)으로 가져오고,
해당 액티비티 위에 다른 액티비티들이 있다면 모두 제거하여 그 액티비티가 실행되도록 합니다.
메모: 인텐트의 플래그가 FLAG_ACTIVITY_CLEAR_TOP인데, 만약 실행하려는 액티비티의 시작 모드가 "standard"이면, 기존에 있던
액티비티의 객체를 제거후 다시 생성하여 태스크에 넣습니다. 시작 모드가 "standard"일때는 시스템이 새 액티비티를 일단 생성하고
보기 때문입니다.
친밀도(affinity) 다루기
친밀도(affinity)는 액티비티가 어떤 태스크에 속하고 싶어하는가를 지정할 수 있습니다.
기본적으로 같은 앱에 속한 액티비티들은 같은 친밀도(패키지명)를 가지고 있기 때문에, 같은 태스크에 속하고 싶어하지만,
액티비티의 친밀도를 바꿀 수 있습니다. 서로 다른 앱의 액티비티들이 같은 친밀도를 가질 수도 있고, 하나의 앱의 액티비티들이 다른 친밀도를
가질 수도 있습니다.
친밀도는 매니페스트 파일의 <activity> 요소에 taskAffinity 속성을 통해 지정할 수 있습니다.
taskAffinity 속성의 기본값은 <manifest>에 선언된 패키지명이며 이것이 앱의 친밀도이기 때문에 내 앱에서 다른 태스크를 생성하고자
taskAffinity를 지정하는 것이라면 패키지명과 다른 문자열로 지정해야 합니다.
친밀도는 아래의 2가지 상황에서 작동합니다:
- 액티비티를 실행하는 인텐트에 FLAG_ACTIVITY_NEW_TASK가 포함되어 있을 때.
기본적으로 새 액티비티는, 생성될 때 startActivity()를 호출한 액티비티와 같은 태스크에 들어갑니다.
하지만, startActivity()에 넘긴 인텐트에 FLAG_ACTIVITY_NEW_TASK가 포함되어 있다면, 시스템은 액티비티의 친밀도와 같은 태스크를 찾습니다.
만약 그러한 태스크가 존재한다면 그 태스크에 새 액티비티를 넣고, 존재하지 않는다면 새 태스크를 생성합니다.
만약 이 플래그를 이용하여 새 태스크를 만들었는데 사용자가 홈버튼을 눌러 빠져나간 경우 다시 그 태스크로 가고 싶다면, 그 태스크로 이동할 수 있는 방법이 존재해야 한다는 것을 개발시 고려해야 합니다. (노티피케이션 매니저와 같은) 일부 요소들은 항상 다른 태스크에서 액티비티를
실행하기 때문에, startActivity()에 넘기는 인텐트에 항상 FLAG_ACTIVITY_NEW_TASK를 설정합니다.
만약 이러한 방식으로 액티비티가 실행되었다면, 사용자가 그 태스크로 이동할 수 있는 독립적인 방법이 있어야 합니다.
예를 들면, 태스크의 root에 있는 액티비티가 매니페스트에 선언될 때 인텐트 필터에 CATEGORY_LAUNCHER가 선언되어 있다면,
런처화면에 아이콘이 제공되어 그 아이콘을 누르면 그 태스크로 이동하게 됩니다. 태스크를 시작하는 것과 관련한 자세한 내용은
태스크 시작하기에서 학습하실 수 있습니다. - <activity>의 allowTaskReparenting 속성값이 "true"일 때.
이 경우에, 액티비티가 현재는 자신이 시작된 태스크에 있다하더라도, 자신과 친밀도가 같은 태스크가 전면(foreground)으로 나올 때,
그 태스크로 이동할 수 있습니다. 예를 들어, 어떤 여행 앱에, 선택된 도시의 날씨 정보를 보여주는 액티비티가 있다고 가정해 봅시다.
그 액티비티는 여행 앱의 다른 모든 액티비티들과 같은 친밀도를 가지고 있고, allowTaskReparenting이 true로 지정되어 있습니다.
내 앱에서 그 날씨 정보 액티비티를 실행하면, 그 액티비티는 그것을 실행한 내 액티비티의 태스크에 들어갈 것입니다.
하지만, 여행 앱의 태스크가 전면(foreground)으로 나올 때, 그 날씨 정보 액티비티는 여행 앱의 태스크로 옮겨질 것입니다.
팁: 만약 하나의 .apk파일이 사용자 관점에서 2개 이상의 "앱"으로 구성되어 있다면, 각 "앱"에 해당하는 액티비티들에 대하여 각각의 친밀도를
부여할 수도 있을 것입니다.
백스택 비우기
만약 사용자가 태스크에서 오랜 시간 벗어나 있었다면, 시스템은 그 태스크의 root 액티비티만 남기고 나머지는 모두 제거합니다.
사용자가 다시 그 태스크에 돌아왔을때는 root에 있던 액티비티 하나만 남아있겠죠.
시스템이 이렇게 동작하는 이유는, 사용자가 어떤 태스크에서 벗어나 오랜 시간이 지났다면 아마도 이전에 뭘했는지를 잊었을 것이고
다시 돌아왔을때는 새로 시작하는 것이 나을 것이라고 판단하기 때문입니다.
하지만 이러한 동작도 액티비티의 몇가지 속성을 통해 바꿀 수 있습니다:
alwaysRetainTaskState
태스크의 root 액티비티의 이 속성이 "true"이면, 오랜 시간이 지나도 액티비티들을 제거하지 않고 모든 액티비티들을 유지합니다.
clearTaskOnLaunch
태스크의 root 액티비티의 이 속성이 "true"이면, 사용자가 이 태스크에서 벗어났다가 다시 돌아올 때, (벗어나 있던 시간과 상관없이)
root 액티비티만 남기고 나머지는 모두 제거합니다. 달리 말하면, alwaysRetainTaskState 속성과 반대되는 속성이라고 할 수 있습니다.
사용자가 아주 잠깐 벗어났다가 돌아오더라도 태스크는 초기 상태가 되는 것입니다.
finishOnTaskLaunch
이 속성은 clearTaskOnLaunch와 비슷하지만, 태스크가 아닌 하나의 액티비티(root 액티비티 포함)에 대해서 동작합니다.
이 속성이 "true"일 때, 액티비티는 오직 태스크가 전면(foreground)에 있을 때만 태스크 안에 유지될 수 있습니다.
사용자가 태스크에서 벗어났다가 돌아올 경우에 그 액티비티는 제거됩니다.
태스크 시작하기
태스크의 진입점을 나타내기 위해, 액티비티에 액션값이"android.intent.action.MAIN"이고
카테고리가"android.intent.category.LAUNCHER"인 인텐트 필터를 선언할 수 있습니다.
예제 코드:
<activity ... >
<intent-filter ... >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
...
</activity>
위의 인텐트 필터는 액티비티에 설정된 아이콘과 이름을 앱의 런처화면에 보이게 해줍니다.
이는 사용자가 그 액티비티를 실행할 수 있도록 하고 액티비티 실행후 태스크에서 벗어나더라도 언제던지 런처를 통해 태스크로 돌아올 수 있게 합니다.
위에서 두번째로 얘기한, 태스크로 돌아올 수 있게 한다는 기능이 중요합니다
: 사용자들은 태스크에서 벗어났다가 액티비티 런처를 통해 다시 돌아올 수 있어야 합니다.
이 때문에, 새 태스크를 생성할 수 있는 2가지 시작 모드인 "singleTask"와 "singleInstance"는, 액티비티가
ACTION_MAIN과 CATEGORY_LAUNCHER 필터를 가지고 있을 때만 사용하는 것이 좋습니다.
이러한 필터가 없이 실행된 경우를 상상해 보세요: 시작 모드가"singleTask"인 액티비티를 실행하여 새 태스크가 생성되었고,
사용자가 거기서 홈버튼을 눌러 벗어났다면, 이제 그 태스크는 후면(background)으로 들어가게 되고 더이상 보이지 않습니다.
그 액티비티에는 위의 인텐트 필터가 없다고 했기 때문에 런처 화면에 보이지 않을 것입니다.
따라서 (내 앱이 태스크를 실행하지 않는 한) 이제는 사용자가 그 태스크로 돌아갈 방법이 없습니다.
Activity 생성시 Intent Flag
사용방법은 다들 알고 있겠지만 다음과 같음
예) intent.addFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
1. FLAG_ACTIVITY_BROUGHT_TO_FRONT
: 시스템에서 설정하는 값이며, 같은 task에 Activity가 존재할 경우에 Activity의 실행모드가 singleTask이면 자동으로 설정됨
2. FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
: 테스크가 리셋될 때 플래그가 사용된 액티비티부터 위의 액티비티가 모두 삭제됩니다.
예) ABCD -> B call - > AB
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED플래그의 설정에 의해 리셋이 이루어지게 됩니다.
시스템에 의해 홈에서 사용자에 의해 백그라운드에 있던 태스크가 포그라운드로 전환될때에 항상 붙게 됨.
3. FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
: 인텐트를 이용하여 새로운 테스크를 생성하거나 존재하고 있는 테스크를 포그라운드로 가져오는 경우가 아닌 경우에는
아무런 효과가 없는 플래그 적절한 경우에 테스크를 리셋하게 되는데, 테스크의 affinity설정에 맞추어 리셋이 발생하게 됩니다.
위에 FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET과 같은 플래그 설정에 맞추어진 특정 처리가 일어나게 됨.
4. FLAG_ACTIVITY_CLEAR_TOP
: 호출하는 액티비티가 스택에 존재할 경우에, 해당 액티비티를 최상위로 올리면서, 그 위에 존재하던 액티비티들은 모두 삭제를 하는 플래그
예를 들어 ABCDE가 존재하는 상태에서 C를 호출하게 되면 ABC만 남게 됩니다.
5. FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
: 실행되는 액티비티들은 최근 실행목록에 표시가 되게 됩니다. 그러나 이러한 표시를 하지 않길 원하는 액티비티가 존재할 경우에
해당 플래그를 넣어주게 되면, 최근 실행목록에 표시가 되지 않게 됩니다.
6. FLAG_ACTIVITY_FORWARD_RESULT
: startActivityForResult를 이용하여서 Activity를 호출할 경우에, 호출하는 쪽이 아닌 한번 더 거쳐서 Result를 받고 싶을 경우가 있다.
이러한 경우에 사용하면 되며, A->B->C 일 경우에 C에서 setResult를 설정하여주고, B에서 finish를 하게 되면 A에서는 C의 값을 받을수 있습니다.
7. FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
: 시스템에 의해서 설정되는 플래그. 최근실행목록에서 실행되게 되면 자동으로 설정됨
8. FLAG_ACTIVITY_MULTIPLE_TASK
: FLAG_ACTIVITY_NEW_TASK와 함께 사용하여야 하며 혼자만 사용할 경우 아무 소용이 없습니다.
두개의 플래그를 동시에 사용할 경우 새로운 태스크는 재활용되지 않고 무조건 새로 생성되며 피호출되는 엑티비티는
이 새로운 태스트의 최상위 엑티비티가 됩니다.
9. FLAG_ACTIVITY_NEW_TASK
: 새로운 테스크를 생성하여 그 테스크안에 액티비티를 추가할때 사용합니다.
단, 기존에 존재하는 테스크들중에 생성하려는 액티비티와 동일한 affinity를 가지고 있는 테스크가 있다면 그곳으로 액티비티가 들어가게 됩니다.
하나의 어플리케이션안에서는 모든 액티비티가 기본 affinity를 가지고 같은 테스크안에서 동작하는 것이 기본적이지만,
FLAG_ACTIVITY_MULTIPLE_TASK 플래그와 함께 사용 하지 않을 경우 무조건적으로 테스크가 새로 생성되는것은 아님을 주의하여야 합니다.
10. FLAG_ACTIVITY_NO_ANIMATION
: 액티비티 전환시 애니메이션을 무시합니다.
11. FLAG_ACTIVITY_NO_HISTORY
: 액티비티가 스택에 존재하지 않게 되도록 합니다. 로딩화면등에 이용
12. FLAG_ACTIVITY_NO_USER_ACTION
: 이 플래그가 설정되면 자동적으로 액티미티가 호출될 경우에 자동 호출되는 onUserLeaveHint()가 실행되는 것을 차단합니다.
onUserLeaveHint() 콜백 메서드는 어플리케이션 사용중에 전화가 온다거나 하는 등의 사용자의 액션없이 액티비티가 실행/전환되는 경우에
호출되는 메서드 입니다.
13. FLAG_ACTIVITY_REORDER_TO_FRONT
: 이 플래그를 이용하게 되면 호출하려는 Activity가 스택에 존재할 경우에, 최상위로 올려주는 효과를 가지게 됩니다.
예를 들어 ABCDE가 있을 경우 C를 호출하게 되면 ABDEC순서로 정렬이 변경되게 됩니다.
14. FLAG_ACTIVITY_SINGLE_TOP
: 호출되는 Activity가 최상위에 존재할 경우에는 해당 Activity를 다시 생성하지 않고, 존재하던 Activity를 다시 사용하게 됩니다.
예를 들면 ABC가 존재하는 경우에 C를 호출하게 되면 기존과 동일하게 ABC가 나오게 됩니다.
[Android/안드로이드] Task & Back Stack.
http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
'IT_Programming > Android_Java' 카테고리의 다른 글
[펌] Android Studio에 Retrolambda 적용하기 (0) | 2015.12.08 |
---|---|
Fragment에서의 ActionBar 조작은 OnCreateView에서 하자 (0) | 2015.11.30 |
Android Studio 새로운 메모리 분석 도구를 품다! (Hello!! Allocation Tracker) (0) | 2015.11.16 |
오디오 포커스에 대하여 (0) | 2015.11.10 |
Activity에서 onPause() 전에 무조건 onUserLeaveHint() 가 수행될 경우. (0) | 2015.10.30 |