차근차근/Android
태스크 , 어피니티 , 플래그
안드로이드/Android 태스크란? (Task, Activity Stack) 어피니티란? (Android Affinity) 플래그란? (Android Flag)
안드로이드/Android 태스크란? (Task, Activity Stack) 어피니티란? (Android Affinity) 플래그란? (Android Flag)
태스크란? (Task, Activity Stack)
어피니티란? (Android Affinity)
플래그란? (Android Flag)
안드로이드 태스크란? (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를 벗어났다가 다시 돌아오면 더이상 존재하지 않는다 |
안드로이드/Android Flag Activity 사용법 및 주의사항 ~!
http://arabiannight.tistory.com/298
안드로이드 Flag Activity를 사용해서 Activity Stack에 작업을 진행 할 때 주의사항 입니다. 대표적으로 사용하는 Flag Activity에는
1) FLAG_ACTIVITY_SINGLE_TOP
2) FLAG_ACTIVITY_CLEAR_TOP
3) FLAG_ACTIVITY_REORDER_TO_FRONT
4) FLAG_ACTIVITY_NO_HISTORY
가 있습니다.
Activity Stack 이란?
안드로이드 시스템은 Activity를 Activity Stack을 통해 관리 하게 됩니다. 기존 Stack의 개념과 동일 하다고 보시면 됩니다.
1) <FLAG_ACTIVITY_SINGLE_TOP>
먼저 "FLAG_ACTIVITY_SINGLE_TOP" Flag 사용시에 주의 사항 입니다.
가장 중요한 주의사항은 바로 동일한 Activity가 연속적으로 사용되어야만 Flag Activity가 적용 된다는 사실 입니다. 그림처럼 동일한 Activity가 연속적으로 사용되지 않는다면 [A]-> [B] -> [C] -> [D] 에 아무리 해당 Flag 속성인 "FLAG_ACTIVITY_SINGLE_TOP" 속성을 적용해도 적용 되지 않습니다. 그냥 차곡차곡 Activity Stack에 쌓이게 됩니다.
그러므로 [A] -> [B] -> [B] 의 형태로 동일한 Activity가 연속적으로 호출되어 Activity Stack에 쌓이게 되면 해당 속성을 이용 할 수 있습니다.
간단하게 속성에 대해 설명 하자면,
동일한 Activity Stack에 연속적으로 쌓이면 Activity를 재사용 하는 Flag 입니다.
재사용 Activity는 onPause(), onNewIntent(), onResume() 순서로 동작하게 됩니다.
기본원리
[A] -> [B] -> [C] -> [D] -> [D] (적용 O) 결과 : [A] -> [B] -> [C] -> [D]
[A] -> [B] -> [A] -> [B] -> [A] (적용 X)
2) <FLAG_ACTIVITY_CLEAR_TOP>
기존에 Activity Stack에 쌓여 있던 Activity에 동일한 Activity 쌓일 경우, RootActivity와 동일한 Activity만 남긴후 Stack에 쌓여 있는 나머지 Activity를 모두 onDestroy() 시켜 버리는 Flag 입니다. 결국 RootActivity와 동일한 Activity 하나가 남게 됩니다.
(RootActivity는 무조건 남게 됩니다.)
기본원리
[A] (RootActivity)
[A] -> [B] -> [C] -> [D] -> [B] (적용 O) 결과 : [A] -> [B]
[A] -> [B] -> [A] (적용 O) 결과 : [A]
[A] -> [B] -> [B] (적용 O) 결과 : [A] - [B]
[A] -> [B] -> [C] (적용 X)
"FLAG_ACTIVITY_CLEAR_TOP" 속성이 적용이 되면
속성이 적용 된 동일한 Activity는 onCreate() 부터 시작
Activity Stack 내에 다른 Activity는 모두 onDestory() 시킴 (RootActivity 제외)
만약 "FLAG_ACTIVITY_CLEAR_TOP" 속성을 적용한 재사용 Activity가 onCreate()가 아닌 재사용을 시키고 싶을 경우에는 "FLAG_ACTIVITY_SINGLE_TOP" 속성과 같이 사용해 주시면 됩니다.
3) <FLAG_ACTIVITY_REORDER_TO_FRONT>
Activity Stack에 동일한 Activity가 쌓일 경우 "FLAG_ACTIVITY_REORDER_TO_FRONT" 속성을 가지고 있다면, 무조건 동일한 Activity를 최상위로 올립니다. 최상위로 올라간 Activity는 onResume() 으로 재시작 됩니다.
(FLAG_ACTIVITY_CLEAR_TOP Flag 무시함)
기본원리
[A] -> [B] -> [C] -> [A] (적용 O) 결과 : [B] -> [C] -> [A]
[A] -> [B] -> [C] -> [D] -> [B] (적용 O) 결과 : [A] -> [C] -> [D] -> [B]
[A] -> [B] -> [C] -> [C] (적용 O) 결과 : [A] -> [B] -> [C]
4) <FLAG_ACTIVITY_NO_HISTORY>
Activity Stack에서 [B] Activity에 "FLAG_ACTIVITY_NO_HISTORY" 속성을 적용하고 [B] -> [C] Activity를 호출 하는 경우,[C] Activity는 스택에서 제거 된다. 하지만 종료 시점은 [D] Activity가 onDestory() 되는 시점에 [C] Activity도 같이 onDestory() 된다.
기본원리
1-1) [A] -> [B] -> [C] - [D] (적용 O) ([B]에 속성 추가)
1-2) [A] -> [B] -> [C] -> [D] ([C]가 스택에서 제거됨) ([D]에서 백키누름)
1-3) [A] -> [B] (결과)
2-1) [A] -> [B] -> [C] -> [C] -> [C] (적용 O) (3번째 [C] 에서 속성 추가)
2-2) [A] -> [B] -> [C] -> [C] -> [C] (4번째 [C] 가 스택에서 제거됨) (5번째 [C]에서 백키누름)
2-3) [A] -> [B] -> [C] (결과)
이렇게 해서 자주 사용하는 Flag Activity에 대해 알아 보았습니다. 다음번 포스팅에서는 좀 더 다양한 Flag Activity에 대해서 알아 보도록 하겠습니다. ~! ^^
감사합니다.
[Android] Activity 생성시에 사용되는 Intent Flag 정리
http://theeye.pe.kr/archives/1298
안드로이드 엑티비티에 대해 이해하기 위해 필요한 지식은 3가지 정도가 아닐까 생각합니다. 바로 Activity Lifecycle, Task, Intent 입니다. 모두 어느정도 이해를 하시고 계신 상태라고 생각하고 글을 적어보겠습니다.
인텐트를 이용하여 새로운 엑티비티를 띄우기 위해서는 일반적으로 다음과 같은 방법으로 새로운 엑티비티를 실행하게 됩니다.
1 2 | Intent intent = new Intent(this, MyActivity.class); startActivity(intent); |
위의 코드는 다음과 같은 순서로 실행이 됩니다.
2. 이 인스턴스가 현재 태스크 스택의 최상단에 푸시가 됩니다.
3. 엑티비티가 시작되며(onStart) 포그라운드로 가져옵니다.
하지만 위와 같은 인텐트 생성에 관련된 기본적인 실행 방법을 인텐트 플래그를 사용하여 임의로 조정할 수 있습니다.
1 | intent.addFlag(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT); |
위와 같은 방법을 통해 특정한 플래그 옵션값을 startActivity(intent)가 수행될때 같이 넘겨줄 수 있습니다. 지금부터 이러한 플래그 옵션값들을 좀더 상세기 적어보도록 하겠습니다.
FLAG_ACTIVITY_BROUGHT_TO_FRONT
이 플래그는 사용자가 설정하는것이 아닌 시스템에 의해 설정되는 값입니다. 엑티비티의 실행모드가 singleTask이고 이미 엑티비티스택에 존재하고 있는 상태라고 가정을 할 때 다시 그 엑티비티가 호출되고 재활용 되었을 경우 자동으로 설정이 됩니다.
FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
이 플래그를 사용하면 태스크가 리셋될때 플래그가 사용된 엑티비티부터 최상단의 엑티비티까지 모두를 삭제합니다. 리셋은 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 플래그에 의해 실행이 되는데 시스템에 의해 홈스크린에서 사용자에 의해 백그라운드에 있던 태스크가 포그라운드로 전환될때에 항상 붙게 됩니다.
위의 그림에서 볼 수 있듯이 백그라운드와 포그라운드 전환관계에서 CLEAR_WHEN_TASK_RESET플래그가 설정된 엑티비티와 이후의 엑티비티 모두가 삭제되는것을 알 수 있습니다. 백그라운드로 넘어갔을때 유지를 안해도 될 일회성 엑티비티들은 해당 플래그를 사용하면 도움이 될것이라 봅니다.
FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
이 플래그는 인텐트를 이용하여 새로운 태스크를 생성하거나 존재하고 있는 태스크를 포그라운드로 가져오는 경우가 아닌경우에는 사용하여도 아무런 효과가 없습니다. 적절한 경우라면 태스크를 리셋 합니다. 이때에 태스크의 affinity 설정에 맞추어 리셋이 일어나게 되며FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET과 같은 플래그 설정에 맞추어진 특정 처리가 일어나게 됩니다.
FLAG_ACTIVITY_CLEAR_TOP
만약에 엑티비티스택에 호출하려는 엑티비티의 인스턴스가 이미 존재하고 있을 경우에 새로운 인스턴스를 생성하는 것 대신에 존재하고 있는 엑티비티를 포그라운드로 가져옵니다. 그리고 엑티비티스택의 최상단 엑티비티부터 포그라운드로 가져올 엑티비티까지의 모든 엑티비티를 삭제합니다.
예를 들면 현재 ABCDE순서로 엑티비티가 스택에 들어있다고 할때 엑티비티E에서 C를 호출하게 되면 D와 E는 스택에서 삭제되고 ABC만이 남아있게 됩니다. 여기서 AB 역시 남는다는 것을 이해하셔야 합니다.
FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
엑티비티가 새로운 태스크안에서 실행될때에 일반적으로 타겟 엑티비티는 ‘최근 실행된 엑티비티’목록에 표시가 됩니다. (이 목록은 홈버튼을 꾹 누르고 있으면 뜹니다) 이 플래그를 사용하여 실행된 엑티비티는 최근실행된엑티비티 목록에서 나타나지 않습니다.
FLAG_ACTIVITY_FORWARD_RESULT
기본적으로 엑티비티A가 엑티비티B를 호출하였다고 할 경우 startActivity(intent) 대신에startActivityForResult(intent) 메서드를 이용하여 호출을 함으로써 엑티비티B의 결과값을 엑티비티A로 전달할 수 있습니다.
엑티비티B에서는 setResult(int resultCode)를 정의한 뒤에 종료를 하게 되며 엑티비티B를 호출하였던 엑티비티A는 콜백메서드인 onActivityResult()를 통해 결과값을 전달받게 됩니다.
이제 엑티비티B가 또다른 엑티비티C를 호출하였다고 가정해 봅시다. 그리고 이렇게 호출된 엑티비티C에서 엑티비티A까지 전달할 결과값을 정의하였습니다. 이 결과값을 B에서 A로 또다른 코드를 통해서 프로그래머의 코드를 통해서 값을 전달하는 번거로움을 피하기 위해 안드로이드에서는 이 인텐트 플래그값을 제공합니다.
위에 나와있는 그림의 예를 통해 보면 엑티비티B가 엑티비티C를 호출하기위해 단순히startActivity()를 이용하는 것을 알 수 있습니다. 그리고 지금 설명중인 플래그를 붙이도록 합니다. 이후에 엑티비티C에서는 setResult()를 통해 결과값을 정의를 한후에 finish()를 통해 엑티비티를 종료하도록 합니다.
엑티비티B에서는 단순히 마찬가지로 finish()를 통해 엑티비티를 종료하시기만 하면 됩니다. 이후에startActivityForResult()를 통해 엑티비티B를 호출했던 엑티비티A는 onActivityResult() 콜백 메서드로 결과값을 받아보시면 엑티비티C에서 정의한 값을 받을 수 있다는것을 알 수 있습니다.
FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
이 엑티비티 플래그는 시스템에 의하여 자동으로 설정되는 플래그입니다. 홈스크린화면에서 홈버튼을 롱클릭함으로써 뜨게 되는 “최근실행목록”을 통해 실행되었을 경우 자동으로 설정됩니다.
FLAG_ACTIVITY_MULTIPLE_TASK
이 엑티비티 플래그는 FLAG_ACTIVITY_NEW_TASK와 함께 사용하지 않으면 아무런 효과가 없는 플래그입니다. 두개의 플래그를 동시에 사용할 경우 새로운 태스크는 재활용되지 않고 무조건 새로 생성되며 피호출되는 엑티비티는 이 새로운 태스트의 최상위 엑티비티가 됩니다. (당연히 하나밖에 없을테니-_-a)
FLAG_ACTIVITY_NEW_TASK
이 엑티비티 플래그를 사용하여 엑티비티를 호출하게 되면 새로운 태스크를 생성하여 그 태스크안에 엑티비티를 추가하게 됩니다. 단, 기존에 존재하는 태스크들중에 생성하려는 엑티비티와 동일한affinity를 가지고 있는 태스크가 있다면 그곳으로 새 엑티비티가 들어가게됩니다.
하나의 어플리케이션안에서는 모든 엑티비티가 기본 affinity를 가지고 같은 태스크안에서 동작하는것이 기본적(물론 변경이 가능합니다)이지만 FLAG_ACTIVITY_MULTIPLE_TASK 플래그와 함께 사용하지 않을경우 무조건적으로 태스크가 새로 생성되는것은 아님을 주의하셔야 합니다.
FLAG_ACTIVITY_NO_ANIMATION
안드로이드 OS가 2.0으로 올라오면서 새로 추가된 엑티비티 플래그입니다. 이 플래그를 사용할 경우 엑티비티가 스크린에 등장할시에 사용될 수 있는 다양한 애니메이션 효과를 사용하지 않습니다.
FLAG_ACTIVITY_NO_HISTORY
이 플래그를 사용할 경우 새로 생성되는 엑티비티는 어떤 태스크에도 보존되지 않게 됩니다. 예를 들면 로딩화면과 같이 다시 돌아오는것이 의미가 없는 화면이라면 이 플래그를 사용하여 태스크에 남기지 않고 자동적으로 화면이 넘어감과 동시에 제거할 수 있습니다.
FLAG_ACTIVITY_NO_USER_ACTION
이 플래그가 설정되면 자동적으로 엑티비티가 호출될 경우에 자동 호출되는 onUserLeaveHint()가 실행되는것을 차단합니다. onUserLeaveHint() 콜백 메서드는 어플리케이션 사용중에 전화가 온다거나 하는등의 사용자의 액션없이 엑티비티가 실행/전환되는 경우에 호출되는 메서드입니다.
FLAG_ACTIVITY_REORDER_TO_FRONT
호출하려던 엑티비티가 이미 엑티비티 스택에 존재하고 있다면 이 플래그를 사용하여 스택에 존재하는 엑티비티를 최상위로 끌어올려줍니다. 결과적으로 엑티비티 스택의 순서가 재정렬되는 효과를 가집니다. 위의 예를 볼 경우에 엑티비티E가 C를 호출하게 됨으로써 엑티비티C가 최상단으로 이동하는 결과를 확인하실 수 있습니다.
FLAG_ACTIVITY_SINGLE_TOP
이 플래그는 말그대로 하나의 탑(?)을 의미하는 설정입니다. 엑티비티를 호출할 경우 호출된 엑티비티가 현재 태스크의 최상단에 존재하고 있었다면 새로운 인스턴스를 생성하지 않습니다. 예를 들어ABC가 엑티비티 스택에 존재하는 상태에서 C를 호출하였다면 여전히 ABC가 존재하게 됩니다.
액티비티와 태스크(Task)
'차근차근 > Android' 카테고리의 다른 글
tabactivity 대체 (0) | 2014.10.16 |
---|---|
안드로이드 탭 (0) | 2014.10.15 |
requestWindowFeature(Window.FEATURE_NO_TITLE); (0) | 2014.10.15 |
onCreate(Bundle savedInstanceState) (0) | 2014.10.15 |
Android View 관련된 오픈소스 정리 (0) | 2014.10.15 |
'차근차근/Android'의 다른글
- 현재글태스크 , 어피니티 , 플래그