Android 태스크 관리

timothy jeong·2021년 11월 12일
0

Android with Kotlin

목록 보기
39/69

태스크 관리란 액티비티를 어떻게 생성하고 관리하는지를 제어하는 일을 의미한다. 시스템에는 액티비티의 태스크를 유지하는 기본 규칙이 있으며 일반적으로는 이 기본 규칙을 그대로 이용하므로 개발자가 태스크를 제어할 일은 많지 않다. 그런데 특정한 상황에서 개발자가 액티비티의 태스크를 관리해야 한다면 설정을 추가해야한다.

시스템에서 태스크 관리

액티비티 태스크란 앱이 실행될 때 시스템에서 액티비티의 각종 정보를 저장하는 공간이다. A 액티비티와 B 액티비티로 구성된 앱이 있다고 하자. A 액티비티에서 인텐트로 B 액티비티를 실행했다면 액티비티 객체가 2개 생성되고 시스템은 이 액티비티가 실행되었다는 정보를 저장하려고 태스크를 만든다.

마치 스택영역처럼, 태스크의 최상단에 있는 액티비티가 화면에 출력된다. 이 상태에서 사용자가 홈 버튼을 눌러 런처 화면으로 나갔다가 앱을 다시 실행하면 저장된 태스크 정보가 그대로 적용되어 화면에는 태스크 위쪽에 있는 액티비티가 나타난다.

사용자가 뒤로 가기 버튼을 누른다면 앱 태스크의 최상단의 액티비티를 종료하고 다시 태스크 위쪽에 있는 액티비티를 화면에 출력한다.

이상의 설명으로는 앱마다 태스크가 하나 존재할거라고 생각할 수 있지만, 앱과 앱이 연동되는 경우가 있기 때문에 꼭 그렇지는 않다. A 앱에서 A-1 -> A-2 순으로 액티비티가 실행되고, A-2 에서 B앱의 B-1 액티비티를 실행하는 경우를 생각해보자, 이때 액티비티 태스크에는 밑에서부터 A-1, A-2, B-1 순으로 쌓일 것이다. B-1 은 B앱의 액티비티이지만 A 앱의 액티비티 태스크에서 관리가 된다. 여기서 태스크는 사용자 관점에서 프로그램의 논리적인 실행 단위라고 할 수 있다. 내부적으로는 앱이 2개 실행된 거지만, 사용자 입장에서는 하나의 앱에서 화면이 3개가 나온 것이다.

그런데 이런 상황에서 사용자가 B앱을 따로 실행하면 어떻게 될까? A앱의 태스크와 B앱의 태스크는 개별적인것이고, 액티비티는 실행되면 새로운 객체가 생성되기 때문에 전혀 영향을 주지 않게 된다.

태스크 제어

이상 시스템에서 태스크를 제어하는 방벙이었다. 이제는 개발자가 원하는대로 액티비티 객체가 생성되고 태스크에 등록되도록 제어하는 방법을 살펴보자. 2가지 방법이 있는데,

  • 액티비티가 등록되는 Manifest 파일의 activity 태그의 launchMode 를 이용한다.
  • 인텐트의 flags 정보를 설정하여 제어한다.
<activity android:name=".SomeActivity" androud:launchMode="singleTop">
val intent = Intent(this, SomeActivity::calss.java)
intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP
startActivity(intent)

메니페스트에 등록하면 항상 적용되고, 인텐트에 플래그로 등록하면 해당 인텐트 정보가 넘어갈 때만 적용된다.

태스크 모드

스탠더드

메니페스트에서 실행 모드를 standard 로 설정하면 설정하지 않은 기본값과 같다. 액티비티에서 인텐트가 발생하면 항상 객체가 생성되고 태스크에 등록된다.

A-1 액티비티에서 A-1 을 다시 실행시키면 앱 태스크에 A-1 이 두개 쌓이게 된다.

싱글톱

실행 모드를 singleTop 으로 설정하면 액티비티 정보가 태스크의 위쪽에 있을 때 인텐트가 발생해도 객체를 생성하지 않는다. 원래 액티비티는 인텐트만 발생하면 무조건 객체가 생성되어야 하지만 singleTop 실행 모드로 설정한 액티비티가 태스크 위쪽에 있으면 어디선가 그 액티비티를 실행하는 인텐트가 발생해도 객체가 생성되지 않는다.

A-1가 앱 태스크의 최상위에 있을때 A-1 을 다시 실행시켜도 앱 태스크에 A-1 이 하나밖에 쌓이지 않는다.

객체가 생성되지 않는 대신 onNewIntent() 함수를 액티비티에 재정의해 놓으면 singleTop 으로 설정한 액티비티 객체가 태스크의 위쪽에 있을 때 엔텐트로 자신을 다시 실행하면 자동으로 호출된다.

override fun onNewIntent(intent: Intent) { ... }

하지만, A-1이 최상위가 아니라면 다시 객체를 생성해서 앱 태스크에 쌓기 때문에 A-1 은 2개가 된다. 그럼 싱글톤을 써야할 때는 언제일까? 바로 액티비티가 화면에 출력되는 상황에서 똑같은 액티비티를 인텐트로 다시 실행하는 상황, 예를 들면 알림을 보내야하는 상황이다. 알림을 보낼때 인텐트를 만들어서 시스템에 알려주었다. 알람을 받음과 동시에 화면에 변화가 생겨야 하는 상황에서 동일한 액티비티가 태스크의 위에 생성되면 뒤로 가기를 눌렀을때 업데이트 되기 전 화면이 나오는 등 유저 경험에 긍정적이지 않을 것이다. 이때는 onNewIntent() 함수에서 화면의 업데이트를 시행해주면 이러한 문제가 발생하지 않는다.

싱글 태스크

실행 모드를 singleTask 로 설정하면 새로운 '태스크'를 만들어서 등록한다. 새로운 액티비티 객체가 아니라 태스크 자체를 따로 만드는 것이다. singleTask 설정은 같은 앱에서는 적용되지 않고 다른 앱의 액티비티를 인텐트로 실행할 때에만 적용된다. 기본적으로 태스크는 앱 하나에 상응되는 것이기 때문에 싱글 태스크로 설정하면 사용자가 새로운 앱을 실행하지 않더라도 하나의 태스크를 다시 만들 수 있게 된다. 기기에 따라 다르지만 태스크가 바뀌면 화면 전환 애니메이션 효과가 나타날 수 있기 떄문에 새로운 앱이 실행되는 것을 사용자에게 알리고 싶을때 사용한다.

각각의 액티비티를 아래의 순서대로 실행한다고 할때, B-1 액티비티를 실행하는 인텐트가 singleTask 로 들어왔다면, A-1, A-2 와 B-1, B-2 가 서로 다른 태스크에 쌓이게 되며, 앱에는 B-2 액티비티가 전개한 화면이 표시된다.

A-1 -> A-2 -> B-1(singleTask) -> B-2

싱글 인스턴스

실행 모드를 singleInstance 로 설정하면 싱글 태스크 처럼 새로운 태스크를 만들어 등록하는 데, 그 태스크에는 해당 설정이 적용된 액티비티 단 하나만 등록된다.

A-1 -> A-2 -> B-1(singleInstance) -> B-2 이렇게 되면 A앱 태스크에 A-1,A-2 가 있고, B 앱 태스크는 2개가 생성되게 된다.

profile
개발자

0개의 댓글