차근차근/Android

안드로이드 어플리케이션 기초3 - 액티비티와 태스크

예쁜꽃이피었으면 2014. 7. 29. 00:40

http://wikiware-textcube.blogspot.kr/2009/12/4-%EC%95%88%EB%93%9C%EB%A1%9C%EC%9D%B4%EB%93%9C-%EC%96%B4%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98-%EA%B8%B0%EC%B4%88.html

 

 

4.3 액티비티와 태스크

 

(1) 태스크(task)

 

어떤 어플리케이션에서 다른 어플리케이션의 기능을 이용하고자 할 경우에 다른 어플리케이션에 Intent 객체를 인자로 startActivity() 메소드를 호출하면 됩니다. 그러면 사용자에게는 타 어플리케이션이 현 어플리케이션의 일부인 것처럼 보이게 됩니다. 실제로 안드로이드는 호출한 액티비티와 호출된 액티비티를 같은 태스크(task) 안에 유지시킵니다.

 

태스크(task)는 사용자가 마치 하나의 어플리케이션인 것처럼 경험하게 하는 것들을 말합니다. 즉, 태스크는 "스택에 쌓여 있는 관련된 액티비티들의 그룹"이라고 말할 수 있습니다. 스택의 밑바닥에 있는 루트 액티비티(root activity)가 태스크를 시작한 것입니다. 보통은 어플리케이션 론처에서 사용자가 선택한 액티비티가 루트 액티비티가 됩니다. 스택의 꼭대기에 있는 액티비티는 현재 동작 중인 포커스된 액티비티입니다.

 

어떤 액티비티가 다른 액티비티를 동작시키면 새로운 액티비티가 스택에 쌓입니다. 휴대폰에서 사용자가 BACK 키를 누르면 이전 화면으로 돌아가는데, 이 때 현재 액티비티가 스택에서 팝(pop)되고 이전 액티비티가 실행됩니다. 따라서 태스크는 "액티비티들이 쌓여 있는 스택"으로 단순히 생각하는 것이 쉽게 이해가 됩니다. 태스크가 매니패스트 파일 안에 있는 어떤 클래스나 요소(element)가 아니므로 오해를 하지 않도록 주의하세요.

 

하나의 태스크 안에 있는 액티비티들은 태스크 단위로 움직입니다. 태스크가 포그라운드(foreground)나 백그라운드(background)로 전환될 때 관련 태스크가 통째로 옮겨집니다. 이런 동작을 바꾸려면 매니패스트 파일의 <activity> 요소의 플래그(flag)나 속성을 변경해야 합니다. 매니패스트 파일의 인텐트 플래그(flag)에는 다음과 같은 것들이 있습니다.

 

  • FLAG_ACTIVITY_NEW_TASK
  • FLAG_ACTIVITY_CLEAR_TOP
  • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
  • FLAG_ACTIVITY_SINGLE_TOP

 

<activity> 요소의 속성에는 다음과 같은 것들이 있습니다.

 

  • taskAffinity
  • launchMode
  • allowTaskReparenting
  • clearTaskOnLaunch
  • alwaysRetainTaskState
  • finishOnTaskLaunch

 

위 플래그나 속성들에 대해서는 자세한 설명을 생략합니다. 후에 다시 설명할 기회가 있을 것입니다.

 

(2) 인척 관계(affinity)

 

기본적으로 한 어플리케이션 안의 모든 액티비티들은 서로 인척 관계(affinity)에 있습니다. 인척 관계라고 하는 것은 같은 태스크에 속할 수 있는지 여부를 나타냅니다. 이런 인척 관계는 다른 어플리케이션과도 맺어질 수가 있습니다. 또한 같은 어플리케이션 안의 액티비티들이 서로 다른 인척 관계를 가질 수도 있습니다. 이런 인척 관계를 설정하는 방법은 매니패스트 파일의 <activity> 요소의 taskAffinity 속성으로 제어를 할 수 있습니다. 인척 관계를 설정하는 2 가지 방법은 다음과 같습니다.

 

  • FLAG_ACTIVITY_NEW_TASK 플래그를 이용한 방법
    기본적으로 startActivity()로 호출된 액티비티는 호출한 액티비티의 태스크에 포함됩니다. 단, startActivity()를 부를 때 intent 객체 인자에FLAG_ACTIVITY_NEW_TASK 플래그가 설정되어 있으면, 시스템이 새 태스크로 새 액티비티를 시작합니다. 기존 태스크에 포함된 경우는 해당 태스크에 포함시킵니다.
  • allowTaskReparenting 속성을 이용한 방법
    이 속성이 “true”인 경우, 어떤 태스크에 포함되어 있다가도 다른 인척 관계에 있는 태스크가 포그라운드가 될 때 이 태스크로 옮겨갈 수 있습니다.

 

(3) 론치 모드(launch mode)

 

<activity> 요소의 launchMode 속성에는 다음과 같은 4 가지가 있습니다.

 

  • "standard" (the default mode)
  • "singleTop”
  • "singleTask”
  • "singleInstance“

 

위 속성들을 해석하는 방법은 다음과 같이 4 가지 관점이 있습니다.

 

  • 인턴트에 반응한 액티비티를 어느 태스크가 소유하는가?
    "standard”나 "singleTop”의 경우는 startActivity()를 호출한 태스크가 호출된 액티비티를 소유합니다. (단, FLAG_ACTIVITY_NEW_TASK 플래그가 인턴트에 있는 경우는 예외입니다.) "singleTask”"singleInstance”의 경우는 항상 루트 액티비티가 됩니다. 즉, 항상 새 태스크가 됩니다.
  • 태스크가 여러 개의 인스턴스를 가질 수 있는가?
    "standard”나 "singleTop”의 경우는 여러 번 인스턴스화될 수 있습니다. 이 말은 하나의 액티비티가 여러 태스크에 속할 수 있다거나, 하나의 태스크에 여러 개의 같은 액티비티가 생길 수 있다는 뜻입니다. "singleTask”"singleInstance“의 경우는 단지 하나의 인스턴스만 가집니다.
  • 한 태스크 안에 같은 액티비티 인스턴스를 2 개 이상 가질 수 있는가?
    "singleInstance”인 경우는 단지 하나의 액티비티만 가지는 태스크를 만듭니다. 다른 액티비티를 부르면 불린 것은 마치FLAG_ACTIVITY_NEW_TASK 플래그가 설정된 것처럼 새로운 태스크로 들어갑니다. "standard”나 "singleTop” 또는 "singleTask”의 경우는 하나의 태스크 안에 여러 개의 액티비티가 포함될 수 있습니다.
  • 새로운 인턴트를 처리할 때 항상 새로운 인스턴스가 생성되는가?
    "standard”
    인 경우는 신규 인텐트는 항상 신규 인스턴스로 반응합니다."singleTop”인 경우는 신규 인텐트는 기존 인스턴스를 재사용하여 반응합니다. (단, 재사용된 액티비티는 타켓 태스크의 꼭대기에 있는 액티비티여야 합니다.) 꼭대기에 있는 액티비티가 아니면 재사용되지 않고 새 인스턴스가 생성되어 스택에 푸쉬(push)됩니다. 아래 그림을 참조 바랍니다.

 

 

 

(4) 스택 지우기

 

사용자가 오랫동안 태스크를 떠나 있으면, 시스템이 자동으로 그 태스크의 액티비티들을 지웁니다. 단 루트 액티비티는 남겨 놓습니다. 이런 경우 사용자가 다시 이 태스크로 돌아 왔을 때 루트 액티비티가 보여지게 됩니다. 이와 같은 동작이 기본 동작입니다. 만약 다른 동작을 하도록 하고 싶으면 앞에서 설명드린  <activity> 요소의 속성으로 제어할 수 있습니다. 다음의 3 가지 속성이 이를 제어하는 속성들입니다.

 

  • alwaysRetainTaskState 속성
    루트 액티비티의 속성이 “true”이면, 오랜 시간이 지나도 그대로 남아 있습니다.
  • clearTaskOnLaunch 속성
    루트 액티비티의 이 속성이 “true”이면, 사용자가 이 태스크를 떠났다가 돌아올 때마다 루트 액티비티만 남겨 놓고 나머지는 스택에서 삭제합니다.
  • finishOnTaskLaunch 속성
    사용자가 이 태스크를 떠났다가 돌아올 때마다 이 속성이 “true”인 액티비티만 스택에서 삭제합니다. 이 경우는 루트 액티비티도 삭제될 수 있습니다.

 

스택을 지우는 다른 방법으로 인턴트 객체의 FLAG_ACTIVITY_CLEAR_TOP 플래그를 사용하는 방법이 있습니다. 이 플래그를 사용하면 수신한 인턴트 객체를 처리할 수 없는 액티비티들이 타켓 태스크 스택에서 모두 삭제됩니다. 즉, 수신한 인턴트 객체를 처리할 수 있는 액티비티가 스택의 꼭대기에 나올 때까지 삭제가 일어납니다. 다만 처리 가능한 액티비티의 론치 모드가 "standard"인 경우는 이 액티비티도 스택에서 삭제되고, 새 액티비티가 생성되어 스택에 푸쉬됩니다. "standard"가 의미하는 것이 새 인턴트는 새 액티비티로 처리하라는 것이기 때문입니다.

 

(5) 진입점(entry point)

 

어떤 태스크의 진입점을 지정하는 방법은 앞에서도 설명하였듯이 매니패스트 파일의 액티비티의 <intent-filter>에 액션은 "android.intent.action.MAIN"을 사용하고, 카테고리는 "android.intent.category.LAUNCHER"를 사용하면 됩니다. 이런 진입점을 가지는 필터에는 아이콘과 라벨도 추가로 지정하여야 어플리케이션 론처에 표시가 됩니다.

 

이런 진입점을 가진 액티비티는 항상 "singleTask나 "singleInstance”로 시작해야 합니다. 왜냐하면 어플리케이션 론처에서 실행 가능한 것이 "singleTask"singleInstance”로 되어 있지 않으면, 실행 후 홈 키를 누른 후에는 다시 기존 태스크로 돌아갈 방법이 업습니다. 이와 비슷한 문제가 FLAG_ACTIVITY_CLEAR_TOP 플래그를 가진 액티비티에도 있습니다. 이런 것들은 활성화된 후에 다시 돌아올 다른 방법을 부가적으로 제공해 주어야 합니다. 만약 다시 돌아올 방법을 제공하지 못하는 경우는  <activity> 요소에 finishOnTaskLaunch를 "true"로 설정하여 종료가 되도록 해야 함에 주의하세요.


반응형