본문 바로가기
Android

Android Task

by 박새영 2021. 11. 14.

 

Task

 

Task는 유저가 앱을 사용하면서 생성된 액티비티 모음입니다.

 

Task는 백 스택을 사용해 액티비티를 관리합니다. 액티비티는 시작되는 순서대로 백 스택에 정렬됩니다.

 

 

Task의 기본 동작

 

테스크와 백 스택의 생성하기

 

사용자가 앱을 처음 시작하면 새 테스크가 생성됩니다. 앱의 액티비티가 새 테스크의 백 스택에 추가됩니다.

 

 

테스크의 백 스택에 새로운 액티비티 추가하기

 

startActivity로 새 액티비티가 시작되면 백 스택의 맨 위에 새 액티비티가 phsh(추가)됩니다.

 

 

백 스택에 있는 액티비티를 제거하기

 

사용자가 뒤로가기를 누르면 맨위에 있던 액티비티가 스택에서 pop(제거) 됩니다.

제거된 액티비티 밑에 있던 액티비티가 스택의 맨위가 됩니다.

맨위가 된 액티비티는 포그라운드 상태가 되고, 이전 UI상태가 복원됩니다.

사용자가 계속 뒤로가기를 눌러서 스택에 모든 액티비티가 사라지면 해당 Task는 사라집니다.

 

 

Task 관리

기본적으로 안드로이드는 위와 같이 Task와 백 스택을 관리하지만, 매니페스트에서 정의한 activity 속성 또는 startActivity()에 전달하는 인텐트에 플래그를 추가해서 액티비티가 테스크에 연결되는 방식 및 백 스택에서 동작하는 방식을 정의할 수 있습니다.

 

 

LaunchMode

  • 런치 모드는 액티비티가 시작할때 현재 테스트와 연결되는 방식입니다.
  • 매니페스트에서 액티비티의 런치모드를 정의하거나 인텐트 플래그에 런치모드를 추가할 수 있습니다.

 

 

매니페스트에서 런치 모드 정의하기

 

매니페스트에서 activity에 launchMode 속성을 다음과 같이 정의할 수 있습니다.

 

standard

  • 기본 모드는 standard 입니다. 액티비티가 시작될때마다 백 스택에 액티비티의 새 인스턴스가 추가되기때문에 같은 액티비티가 여러개 중첩되어 저장될 수 있습니다.

singleTop

  • 시작하는 액티비티가 백 스택의 맨위에 있는 경우가 아니라면 액티비티가 시작될때마다 백 스택에 액티비티의 새 인스턴스가 추가됩니다. 테스크의 스택 맨 위에 기존 액티비티가 있는 경우 새 액티비티를 생성하지 않고 기존 액티비티에서 onNewIntent를 호출해서 새 인텐트를 수신하고 기존 액티비티를 재사용합니다.

singleTask

  • singleTask로 시작하는 액티비티는 기존 테스크가 있어도 시스템은 새로운 테스크를 만들어 시작합니다. 액티비티가 기존의 테스크에 있다면 새 액티비티를 생성하지않고 시스템은 onNewIntent() 호출을 통해 기존 인스턴스에 singleTask 인텐트를 라우팅하고 기존 인스턴스가 새 테스크에서 시작합니다.

singleInstance

  • singleInstance도 항상 새로운 테스크에서 시작되지만 새로운 테스크에는 singleInstance로 시작한 액티비티만 유일하게 존재할수있습니다. 다른 액티비티는 테스크에 추가되지 않습니다.

 

 

 

Intent flags에 런치 모드 추가하기

 

액티비티를 시작할때 startActivity()에 전달하는 인텐트에 테스크를 정의하거나 수정하는 플래그를 포함할 수 있습니다.

 

 

FLAG_ACTIVITY_NEW_TASK

  • 새 테스크에서 액티비티를 시작합니다. 런치모드 singleTask와 동일합니다.

FLAG_ACTIVITY_SINGLE_TOP

  • 시작하려는 액티비티가 현재 액티비티와 같다면 현재 액티비티를 재사용하고 현재 액티비티에서 onNewIntent() 호출로 인텐트를 수신합니다. singleTop과 동일합니다.

FLAG_ACTIVITY_CLEAR_TOP

  • 시작하려는 액티비티가 테스크에 존재하는경우 해당 액티비티의 위에 있는 액티비티를 제거해서 기존 액티비티가 스택의 맨위에 위치하게 합니다. 그리고 기존 액티비티가 onNewIntent()가 호출되고 재개됩니다.
  • 매니페스트에서 standard로 설정된 액티비티가 FLAG_ACTIVITY_CLEAR_TOP를 사용해서 시작되었을때에는 자기 자신도 제거되고 새로 생성됩니다. FLAG_ACTIVITY_NEW_TASK는 액티비티를 재사용합니다.

 

 

onNewIntent()

  • 현재 액티비티를 startActivity로 재시작할 때 인텐트에 FLAG_ACTIVITY_SINGLE_TOP 플래그를 추가하면 액티비티를 새로 만들어 시작하지 않고 기존 액티비티를 재시작하는데 기존 액티비티에 onNewIntent()가 호출됩니다.
    • onPause() → onNewIntent() → onResume()
  • 액티비티가 매니페스트에 런치모드 속성이 singleTop으로 설정된 경우, 액티비티를 재시작할때마다 onNewIntent()가 호출됩니다.
    • onPause() → onStop() → onSaveInstanceState() → onRestart() → onStart() → onNewIntent() → onResume()

 

 

Affinity

  • 어피니티는 액티비티가 속할 테스크를 나타냅니다. 기본적으로 같은 앱의 액티비티들은 전부 같은 어피니티를 가지고 있습니다.
  • 액티비티의 어피니티 정의하기
    • activity 요소의 android:taskAffinity 속성 사용해서 정의하기
      • 액티비티의 어피니티를 정의할 수 있습니다.
      • 고유한 string 타입 값으로 정의합니다.
  • 어피니티가 사용되는 상황
    • FLAG_ACTIVITY_NEW_TASK 플래그로 액티비티가 시작할 때
      • 같은 어피니티의 테스크가 기존에 있는 경우에는 같은 어피니티에 새 액티비티가 시작됩니다. 같은 어피니티가 기존에 없는 경우에 새 테스크에서 시작합니다.
    • activity 요소의 allowTaskReparenting 속성을 True로 설정하기
      • 액티비티가 테스크를 이동하는 것을 허락합니다.