태스크와 백스택

홍승범·2023년 1월 18일
0

Android

목록 보기
1/9

태스크

사용자가 상호작용하는 액티비티 스택에대한 메타데이터와 여러 정보의 컬렉션을 의미하며, 스택 구조로 동작한다. 이 응집단위로 백그라운드 포그라운드 이동을 하게 된다.

백스택

액티비티가 열린 순서대로 저장되어 관리되는 공간을 의미. 백키를 누를 경우 최상단의 액티비티를 제거하고, 새로운 액티비티가 열릴경우 기존 최상단 액티비티가 일시중지되고, 새로운 액티비티가 스택의 최상단에 추가된다.

스택에서 삭제된 액티비티는 시스템이 더이상 상태를 보존하지 않는다.

launchMode

액티비티의 기본 런치모드는 standard. 기본 방식으로도 충분히 잘 동작하지만, 변경해야할 필요성이 있으며, 이 변경을 통해 어떤방식으로 스택에 쌓고 태스크를 관리하는지를 manifest의 런치모드에 기술하게 된다.
런치 모드는 4가지가 있다
1. standard : 액티비티를 시작하면, 항상 새로운 인스턴스를 생성하고 백스택의 최상단에 쌓는다.

2. singleTop : 시작하려는 액티비티 x가 이미 스택의 탑에 있는경우는 그 인스턴스를 재활용하고, onNewIntent를 호출해줌. 탑이 아닌경우는 standard와 동일.
예를 들어 이미 a > b > x > c 가 쌓여있는 상태에서 x를 다시 호출하면 a > b > x > c > x 가 된다는것.

3. singleTask : 액티비티의 인스턴스는 스택내에 단 하나만 존재하며, 태스크의 루트에만 액티비티가 존재할 수 있다. 예를들면 태스크의 스택에 이미 다른 액티비티들이 쌓여있는경우 singleTask인 액티비티가 호출되면 태스크를 새로 생성하고, 해당태스크의 루트로 액티비티가 들어간다

4. singleInstance : singleTask와 마찬가지로 스택내에 단하나만 존재가능하다. 차이점은 스택에 액티비티가 딱 하나. 따라서 이 플래그를 가진 액티비티에서 다른 액티비티를 실행하면, 다른 태스크로 들어가거나, 새로 태스크를 생성하거나.

  • 인스턴스 가능 횟수에 따라 다음과 가이 분류할 수 있다.
    1. 한 태스크내에 여러번 인스턴스화 가능 : standard, singleTop
    1. 한 태스크내에 단 한번만 인스턴스화 가능 : singleTask, singleInstance
      • 이 두놈들은 항상 태스크의 시작점 액티비티를 나타내게 된다.
        • 즉 인텐트 필터에 "android.intent.action.MAIN" 과 카테고리에 "android.intent.category.LAUNCHER"를 지정한 액티비티에만 사용할 것을 강력하게 권장한다.
        • 왜냐면 런처에 있지 않으면 다시 진입할 수가 없기 때문이다.

인텐트 플래그

startActivity의 인텐트에 넣을 수 있는 플래그들이 있다. 그리고 이것은 manifest의 launchMode보다 우선하여 동작한다. 아래는 주요 플래그들에 대한 설명이다.

  1. FLAG_ACTIVITY_NEW_TASK : 새로운 태스크를 생성하고, 그 태스크에 호출하는 액티비티를 추가한다. 단. 기존애 존재하는 태스크중에 생성하려는 액티비티와 동일한 taskAffinity를 가진 태스크가 있으면 그 태스크에 추가된다(무조건 새 태스크가 생성되는건 아니라는 소리)

  2. FLAG_ACTIVITY_SINGLE_TOP : launchMode의 singleTop과 동일한 동작을 함

  3. FLAG_ACTIVITY_CLEAR_TOP : 시작하려는 액티비티가 스택에 존재할경우 스택 위의 다른 액티비티를 모두 날리고 onNewIntent호출 없으면 추가

  4. FLAG_ACTIVITY_NO_HISTORY : 호출하려는 액티비티를 스택에 남기지 않는다. 즉 생성후 다른 액티비티로 넘어간 다음 백키를 눌러도 다시 나타나지 않는다는 것.

    • manifest에 android:noHistory=true로 주어도 된다.
  5. FLAG_ACTIVITY_REORDER_TO_FRONT : 태스크내에 이미 존재하는 액티비티를 호출할 때, 최상위 탑으로 이동시키며 새로 생성하지 않고 재사용. 당연히 스택의 위치도 바뀜. 웬만하면 사용하지 말것.

  6. FLAG_ACTIVITY_MULTIPLE_TASK : FLAG_ACTIVITY_NEW_TASK와 같이 사용해야 효과가 있으며, 무조건 새로운 태스크를 생성하고, 그 태스크의 루트 액티비티로 설정된다.

  7. FLAG_ACTIVITY_RESET_TASK_IF_NEEDED & FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET:

    • FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET 속성으로 쌓여진 액티비티부터 상위의 액티비티들은 태스크가 백그라운드에서 포그라운드로 변할 때 FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 속성이 설정되어있으면 태스크에서 정리됨

    • FLAG_ACTIVITY_RESET_TASK_IF_NEEDED 는 태스크내에 정릳되어야할 액티비티가 있다면, task를 리셋, 태스크의 애피티니에 맞춰 리셋이 발생되며, 새로 태스크를 시작하거나, 백그라운드에서 포그라운드로 올라오는 경우가 아니면 영향을 주지 않는다. 즉 사용자가 런처나 recent screen서 태스크를 시작하는경우에 시스템이 설정한다.

Task Affinity

액티비티마다 정해진 taskAffinity가 있다. 아무것도 지정하지 않으면 기본적으로는 앱의 패키지명을 따르게 된다.

이 속성은 액티비티를 실행할 때 어떤 태스크에 속할지를 결정하기 위한 속성이다. 예를들어 내가 만든 액티비티의 taskAffinity를 유튜브 앱의 것으로 설정하면, 유튜브의 태스크로 내 액티비티가 설정되는것.

해당 속성은 다음 두가지 상황에서 작용한다.

  1. 액티비티를 실행한 인텐트에 FLAG_ACTIVITY_NEW_TASK가 포함되어 있는경우 : 동일한 태스크가 있으면 그쪽 백스택에 추가하고, 아니면 새로 태스크를 생성하거나 하는것을 결정하기 위함
  2. allowTaskReparenting 속성이 true일때 : 자신이 시작된 태스크에서 벗어나, 같은 taskAffinity를 가진 작업이 포어그라운드로 나오면 그 작업으로 이동할 수 있게 된다.(이걸 pip 하면서 잘 이해해 볼 수 있다)

백스택 삭제

사용자가 오랜시간동안 태스크에서 벗어난경우(예를들면 홈으로 나가서 게임을 오래한다던가 하는경우) 시스템은 해당 태스크의 루트 액티비티를 제외한 다른 액티비티를 삭제하는것이 기본 동작임. 동작변경을 위한 manifest에서 선언가능한 속성들이 있다.

  1. alwaysRetainTaskState : false 가 기본이며 true로 설정할경우, 기본동작이 일어나지 않음. 즉 오랜시간 후에도 스택의 모든 액티비티를 유지시킴
  2. clearOnLaunch : false 가 기본이며, true 로 설정할경우, 사용자가 태스크를 떠났다가 다시 돌아올 때마다 스택이 루트 액티비티까지 삭제됨. 즉 초기화됨.
  3. finishOnTaskLaunch : clearOnLaunch와 비슷하지만 태스크 전체가 아니라 액티비티 에서만 동작함. 즉 true로 설정하면, 사용자가 태스크를 잠깐 떠났다가 돌아와도, 액티비티는 사라져있음.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED가 설정되지 않으면 무시됨.

https://bb-library.tistory.com/268
https://ybdeveloper.tistory.com/49
https://developer.android.com/guide/components/activities/tasks-and-back-stack?hl=ko
https://jungwoon.github.io/android/2019/07/15/Activity.html

profile
그냥 사람

0개의 댓글