Activities and Tasks
하나의 액티비티는 또 다른 액티비티를 시작시킬 수 있다. 그렇게 시작시킬 수 있는 액티비티에는 다른 애플리케이션이 정의한 액티비티도 포함된다. 안드로이드에는 그 위치를 보여줄 수 있는 액티비티가 존재한다. 그러므로 여러분의 액티비티에 필요한 모든 것은, 인텐트 오브젝트에 필요한 정보들을 추가한 후 그것을 startActivity()의 파라미터로 전달하는 것이다.
맵 뷰어는 다른 애플리케이션 내에 정의되어 있고 다른 애플리케이션 프로세스 상에서 실행되고 있음에도 불구하고, 사용자에게 맵 뷰어는 여러분의 액티비티처럼 동일한 애플리케이션의 일부분처럼 비춰질 것이다. 안드로이드는 두 개의 액티비티를 같은 태스크내에 유지함으로써 이런 사용자 경험user experience을 유지시킨다. 그것은 하나의 스택 내에 정렬된 관련 액티비티들의 그룹이다. 일반적으로, 그것은 사용자가 애플리케이션 런처에서 선택했던 액티비티이다. 스택의 최상위 액티비티는 현재 실행중인 액티비티이다. 그것은 사용자 액션을 위해 포커스 된 액티비티이다. 하나의 액티비티가 다른 것을 시작할 때 새로운 액티비티는 스택에 푸쉬(push)되며, 실행중인 상태의 액티비티가 된다. 이전 액티비티는 여전히 스택에 남아있다. 사용자가 BACK 키를 누를 때 현재의 액티비티는 스택으로부터 팝(pop)되며, 이전의 액티비티는 실행중인 액티비티로 재개resume된다.
태스크 안에서 모든 액티비티는 하나의 단위로 함께 움직인다. 전체 태스크(전체 액티비티 스택)는 포어그라운드foreground로 가져와 질 수 있으며, 또한 백그라운드background로 보내질 수도 있다. 사용자가 HOME 키를 누르고 애플리케이션 런처로 간다. 그리고 새로운 애플리케이션(실제로 새로운 태스크)을 선택한다. 현재 태스크는 백그라운드로 가고, 새로운 태스크에 대한 루트 액티비티가 보여진다. 그런 다음 잠시 후, 사용자가 홈 스크린으로 돌아가서 이전 애플리케이션(이전 태스크)을 다시 선택한다. 스택에 모두 네개의 액티비티를 가지고 있는 그 태스크가 앞으로 온다. 그곳에서 사용자가 BACK 키를 누르면, 스크린에는 사용자가 조금 전에 떠났던 이전 태스크의 루트 액티비티가 보여지지는 않는다. 대신에 스택의 최상위의 액티비티가 제거되고 같은 태스크 내의 이전 액티비티가 보여진다.
Affinities and new tasks
디폴트로 애플리케이션 내의 모든 액티비티는 서로에 대해 하나의 어피니티affinity를 갖는다. 즉, 동일 태스크에 속하는 그것들 모두에 대해 하나의 설정preference이 존재한다. 하지만 각각의 액티비티에 대한 개별적인 어피니티affinity가 <activity> 엘리먼트의 task Affinity 애트리뷰트를 통해 설정될 수 있다. 다른 애플리케이션들내에 정의된 액티비티들이 하나의 어피니티affinity를 공유할 수도 있으며, 또한 같은 애플리케이션 내에 정의된 액티비티들에게 다른 어피니티affinity가 지정될 수도 있다. 어피니티affinity는 두 가지의 조건하에서 동작하게 된다. 액티비티를 런치하는 인텐트 오브젝트가 FLAG_ ACTIVITY_ NEW_ TASK 플래그를 포함하고 있고, 그리고 액티비티에 allowTaskReparenting 애트리뷰트 값이 “true”로 설정되어 있을 때이다.
Launch modes
네 개의 다른 런치 모드가 <activity> 엘리먼트의 launchMode 애트리뷰트에 지정될 수 있다.
"standard" (the default mode)
"singleTop"
"singleTask"
"singleInstance"
어떤 태스크가 인텐트에 응답하는 액티비티를 보유할 것인가? “standard” 와 “singleTop” 모드에 대해서 인텐트 오브젝트가 FLAG_ACTIVITY_NEW_TASK 플래그를 가지지 않았다면, 그것은 인텐트를 만들었던(그리고 startActivity()를 호출했던) 액티비티가 있는 태스크이다. FLAG_ACTIVITY_NEW_TASK 플래그를 인텐트 오브젝트가 포함하고 있는 경우라면, 이전 섹션의 “어피니티와 신규 태스크”에서 설명된 것처럼 다른 태스크가 선택된다.
새로운 클래스 인스턴스가 새로운 인텐트를 처리하기 위해 런치될 것인가? 디폴트 “standard” 모드에 대해서는, 새로운 인스턴스가 모든 신규 인텐트에 응답하도록 생성된다. 각각의 인스턴스는 단지 하나의 인텐트를 처리한다. “singleTop” 모드에 대해서는, 만약 그것이 타겟target 태스크의 최상위 액티비티 스택에 존재한다면, 이미 존재하는 클래스 인스턴스가 신규 인텐트 처리를 위해 재사용된다. 만약 그것이 최상위에 존재하지 않다면 재사용되지 않는다. 대신 신규 인텐트를 위한 새 인스턴스가 생성되고, 스택에 푸쉬push된다.
그러나 D의 런치 모드가 “singleTop” 이라면, (그것이 스택의 최상위에 있기 때문에) 기존에 있는 인스턴스가 새로운 인텐트를 처리하게 될 것이고 스택은 A-B-C-D로 남는다. 반면 도착한 인텐트가 타입 B 액티비티에 대한 것이라면, B가 “standard”든 “singleTop”이든 상관없이 (B가 스택의 최상위에 없기 때문에) 새로운 B 인스턴스가 런치될 것이다. 그러므로 결과적으로 스택은 A-B-C-D-B가 될 것이다
Clearing the stack
사용자가 오랫동안 하나의 태스크를 떠나 있다면, 시스템은 루트 액티비티를 제외한 모든 액티비티를 태스크에서 제거한다. 사용자가 다시 그 태스크로 돌아왔을 때, 오직 최초의 액티비티만이 존재한다는 것 이외에 그것은 사용자가 그것을 떠났을 때와 같다. 이 아이디어는, 어느정도 시간이 지난 후 사용자는 그들이 이전에 하던 것을 포기했을 것이라는 것이고 뭔가 새로운 것을 시작하기 위해 그 태스크로 돌아왔을 거라고 생각하는 것이다.
alwaysRetainTaskState 애트리뷰트
만약 태스크의 루트 액티비티에 이 애트리뷰트가 “true”로 설정된다면, 앞서 언급된 디폴트 동작은 발생하지 않는다. 태스크는 긴 시간 지난 이후에도 스택 내의 모든 액티비티들을 유지한다.
clearTaskOnLaunch 애트리뷰트
만약 태스크의 루트 액티비티에 이 애트리뷰트가 “true”로 설정된다면, 사용자가 태스크를 떠났다가 다시 돌아올 때마다, 스택은 루트 액티비티를 제외하고 모두 제거된다. 바꾸어 말하면 그것은 alwaysRetainTaskState와 정반대이다. 일시적으로 떠났다고 하더라도, 사용자는 항상 그것의 최초 상태로 태스크에 돌아오게 된다.
finishOnTaskLaunch 애트리뷰트
이 애트리뷰트는 clearTaskOnLaunch와 비슷하다. 그러나 그것은 전체 태스크가 아닌, 하나의 액티비티에서 동작한다. 그리고 그것은 루트 액티비티를 포함한 모든 액티비티를 제거할 수 있다. 이것이 “true”로 설정되면, 액티비티는 현재 세션에 대한 태스크의 부분으로만 남게된다. 만약 사용자가 떠났다가 태스크에 돌아오면 그것은 더 이상 존재하지 않는다.
스택에서 액티비티가 제거되도록 하는 다른 방법이 있다. 만약 인텐트 오브젝트가 FLAG_ACTIVITY_CLEAR_TOP 플래그를 가지고 있고, 타겟target 태스크가 그것의 스택에 해당 인텐트를 처리해야 하는 타입의 액티비티 인스턴스를 이미 가지고 있다면, 그것이 스택의 최상위 존재해서 그 인텐트에 응답할 수 있도록 하기 위해 그 위의 모든 액티비티들은 제거된다. 만약 지정된 액티비티의 런치 모드가 “standard”라면, 그것 또한 스택에서 제거될 것이고, 새로운 인스턴스는 도착한 인텐트를 처리하기 위해 시작될 것이다. 왜냐하면 런치 모드가 “standard” 일 때 새로운 인스턴스는 새로운 인텐트를 위해 항상 생성되기 때문이다.
Starting tasks
액티비티는 그것의 인텐트 필터에 액션을 “android.intent.action.MAIN”으로 지정하고 카테고리를 “android.intent.category.LAUNCHER”로 지정함으로써, 태스크에 대한 시작점으로 설정된다(이 필터 타입의 예제가 이전의 인텐트 필터 섹션에 있다). 이런 종류의 필터는 액티비티에 대한 아이콘과 라벨이 애플리케이션 런처에서 보여지도록 하며, 사용자에게 태스크를 런치하고 태스크가 런치된 이후 언제든 그 태스크로 다시 돌아갈 수 있는 두 가지 방법 모두를 제공한다.
이 두 번째 능력은 중요하다. 사용자는 태스크를 떠날 수도 있어야 하고, 나중에 그것으로 돌아갈 수도 있어야 한다. 이런 이유로, 액티비티가 태스크를 항상 시작시키는 두 개의 런치 모드, 즉 “singleTask”와 “singleInstance”는 액티비티가 MAIN 과 LAUNCHER 필터를 가지고 있을 때만 사용되어야 한다. 예를 들어 만약 이 필터가 없다면 무슨 일이 발생할까? 상상해 보라. 인텐트는 새로운 태스크를 시작하는 “singleTask” 액티비티를 런치하고, 사용자는 그 태스크에서 일을 하면서 약간의 시간을 보낸다. 사용자는 그런 다음 HOME 키를 누른다. 태스크는 이제 뒤에 놓이고, 홈스크린에 의해 가려진다. 그리고 그것은 애플리케이션 런처에서 나타나지 않기 때문에, 사용자는 그곳에 다시 돌아갈 방법이 없게 된다.
FLAG_ACTIVITY_NEW_TASK 플래그에도 비슷한 어려움이 수반된다. 만약 이 플래그가 새로운 태스크를 시작하는 액티비티를 만들고, 사용자가 그곳을 떠나기 위해 HOME 키를 누른다면, 사용자가 그곳으로 다시 돌아갈 수 있는 몇 가지 방법이 있어야 한다. 노티피케이션Notification 매니저와 같은 어떤 엔티티entity들은, 결코 그것들의 소유 영역이 아닌, 외부 태스크에서 액티비티를 시작시킨다. 그러므로 그들은 startActivity()에 파라미터로 전달하는 인텐트에 항상 FLAG_ACTIVITY_NEW_TASK를 놓는다. 만약 여러분이 이 플래그를 사용할 수도 있는 외부 엔티티에 의해 호출될 수 있는 액티비티를 가지고 있다면, 사용자가 그것이 시작된 태스크로 다시 돌아갈 수 있는 독자적인 방법을 갖게 하도록 주의하라.
참고 문서 : http://developer.android.com/guide/topics/fundamentals.html
댓글 없음:
댓글 쓰기