본문 바로가기
2023년 이전/Android

Activity 동작 및 Flag

by JeongUPark 2021. 12. 3.
반응형

안드로이드에서 Activity는 스텍에 각 Activity가 열린 순서대 정렬이 됩니다.

그리고 사용자가 Back 버튼을 누르면 현재 나타난 Activity가 활동이 완료되고 (onBackPressed , onDestroy) 스택에서 팝됩니다.

사용자가 기기이 홈화면에서 앱 런처의 아이콘을 터치하면 앱의 Activity가 포그라운드로 나옵니다. 이 때 앱의 Task가 없으면 (최근에 앱이 사용된 적이 없으면) 새 Activity가 생성되고, 앱이 '기본' 활동이 스택의 루트 활동으로 열립니다.

즉, 스택 LIFO로 Activity가 푸쉬되고 팝되는 형태를 가지고 있습니다.

사용자가 새 Task를 시작하거나 홈 버튼을 눌러 홈화면으로 이동하면 기존 Task는 백그라운드로 이동됩니다.

이때 백그라운드의 activity는 백그라운드에 있는 동안 중지되지만 Task의 백스택은 그대로 유지 됩니다. 즉, 다른 Task가 동작하거나 홈화면에 있는동안 백그라운드의 Task는 포커스를 잃을 뿐이지 사용자가 다시 호출하면 다시 사용할 수 있습니다.

그리고 한 Task에 동일한 activity가 스택으로 쌓일 수 있습니다. 즉, 인스터스화 한 만큼 activity가 스텍에 쌓일 수 있습니다

작업관리

manifest의 activity 속성을 통하여 activity를 관리할 수 있습니다. activity의 속성은 다음과 같습니다.

그리고 activity를 intent로 호출 시 다음과 같은 플레그를 사용할 수 있습니다.

위의 링크들을 누르면 android developer에서 상세 내용을 확인해 볼 수 있습니다.

실행모드정의

실행모드를 통하여 activity의 새 인스턴스가 현재 Task와 연결되는 방식을 정의할 수 있습니다.

manifest 파일 사용

manifest의 activity 속성 중 launchMode 라는 것이 있는데 이 모드를 통하여 실행하는 방식을 결정 할 수 있습니다

standard : 기본 값으로, activity가 시작되면 Task에 activity의 새 인스턴스를 생성하고 인텐트를 인스턴스로 라우팅합니다. activity는 여러번 인스턴스화 할 수 있고, 각 인스턴스를 서로 다른 Task에 속할 수 있으며, 한 Task에 여러 인스터스가 있을 수 있습니다.

singleTop : activity의 인스턴스가 이미 task의 맨 위에 있으면 시스템은 activity의 새 인스턴스를 생성하지 않고 onNewIntent() 메서드를 호출하여 기존 인스턴스로 라우팅합니다.

singleTask : 시스템이 새 Task를 생성하고 새 Task의 루트에 있는 acitivty를 인스턴스화 합니다. 그러나 activity의 인스턴스가 이미 별도의 Task에 있다면 시스템은 새 인스턴스를 생성하지 않고 onNewIntent() 메서드를 호출하여 인텐트를 기존 인스턴스로 라우팅합니다. 활동의 인스턴스가 한 번에 하나만 존재할 수 있습니다.

singleInstance : singleTask 와 동일하지만 , 시스템이 인스턴스를 보유한 작업으로 어떤 다른 활동도 실행하지 않는 다는 점이 다릅니다. 활동은 항상 자체 작업의 단 하나의 유일한 멤버입니다. 이 활동으로 시작된 모든 활동은 별도의 작업으로 열립니다.

인텐트 플래그 사용

FLAG_ACTIVITY_NEW_TASK : activity를 새 Task에서 시작합니다. 지금 시작하고 있는 activity에 대해 이미 실행 중인 Task가 있으면 그 Task의 마지막 상태가 복원되어 포그라운드로 이동하고 활동은 onNewIntent() 의 새 인텐트를 수신합니다. 이 플래그를 사용하면 이전 섹션에서 설명한 "singleTak" 값과 동일한 동작이 발생합니다.

FLAG_ACTIVITY_SINGLE_TOP :

시작 중인 activity가 현재 activity(백 스택의 맨 위에 있는)이면 activity의 새 인스턴스가 생성되는 대신 기존 인스턴스가 onNewIntent()호출을 수신합니다.이 플래그를 사용하면 이전 섹션에서 설명한  "singleTop" 값과 동일한 동작이 발생합니다.

FLAG_ACTIVITY_CLEAR_TOP : 시작 중인 activity가 현재 Task에서 이미 실행 중이면 activity의 새 인스턴스가 실행되는 대신 Task의 맨 위에 있는 다른 모든 activity가 제거되고 이 인텐트가 onNewIntent() 를 통해 활동(이제 맨 위에 있음)의 다시 시작된 인스턴스로 전달됩니다. 그리고 FLAG_ACTIVITY_CLEAR_TOP은 FLAG_ACTIVITY_NEW_TASK와 함꼐 자주 사용됩니다. 이러한 플래그를 함꼐 사용하면 또 다른 Task에 있는 기존 activity를 찾아 인텐트에 응답할 수 잇는 위치에 activity를 넣을 수 있습니다.

어피니티 처리

어피니티는 activity가 어느 Task에 소속되기를 선호하는지를 나타냅니다.

그래서 manifest의 activity요소의 taskAffinity 속성을 통해서 어피니티를 수정할 수 있습니다.

그리고 어피니티는 다음 2가지 상황에서 작용합니다.

  • 활동을 실행한 인텐트에 FLAG_ACTIVITY_NEW_TASK 플래그가 포함되어 있을 때
  • 활동의 allowTaskReparenting 속성이 "true"로 설정되어 있을 때

백스택 삭제

사용자가 오랜 시간동안 Task에서 떠나 있으면 시스템은 루트 Activity를 제외한 모든 activity를 Task에서 삭제합니다. 사용자가 작업으로 다시 돌아오면 루트 활동만 복원됩니다. 시스템이 이런 방식으로 동작하는 이유는 오랜 시간이 지나면 사용자가 이전에 하고 있던 일을 그만두고 작업으로 돌아왔을 때 새로운 일을 시작할 가능성이 크기 때문입니다.

이 동작을 수정하는데 사용하는 속성은 다음과 같습니다.

alwaysRetainTaskState : true로 할 경우 Task에서 오랜 시간 지난 후에도 스택의 모든 activity를 유지합니다.

clearTaskOnLaunch : true로 할 경우 사용자가 Task를 떠났다가 다시 Task로 돌아 왔을 때 마다 스택의 루트 activity까지 삭제 됩니다. 즉, 사용자는 항상 Task의 초기화 상태로 다시 실행하개 됩니다

finishOnTaskLaunch : clearTaskOnLaunch와 비슷하지만 작업 전체가 아니라 단일 activity에서 동작합니다. 또한 이 속성을 사용하면 루트 활동을 포함하여 어떤 활동이라도 지울 수 있습니다. 이 속성을 "true"로 설정하면 활동은 현재 세션에 대해서만 작업의 일부로 유지됩니다. 사용자가 작업을 떠났다가 다시 돌아오면 이 작업은 더 이상 존재하지 않습니다.

작업 시작

menifest의 activity 속성에

"android.intent.action.MAIN"을 작업으로 지정하고 "android.intent.category.LAUNCHER" 를 카테고리고 지정하면 Task의 진입점으로 설정할 수 있습니다

<activity ... >
        <intent-filter ... >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        ...
    </activity>
반응형