brunch

You can make anything
by writing

C.S.Lewis

by 서준수 Jun 16. 2019

안드로이드 액티비티 생명주기(Life Cycle)

4대 컴포넌트

안드로이드 액티비티 생명주기


액티비티는 안드로이드 4대 컴포넌트 중에 하나이다. 그중에서도 UI와 가장 밀접한 관련을 가지고 있기 때문에 사실상 안드로이드 앱에 있어서 가장 기본이 되는 구성 요소이다. 보통 앱은 하나 이상의 액티비티가 서로 연결된 형태로 구성된다.


우리가 많이 사용하는 카카오톡을 예 들어보자. 처음 실행을 하면 카카오톡 로고 화면이 잠시 보인 후 마지막으로 사용했던 탭으로 진입한다. 이때 로고가 보이는 화면이 하나의 액티비티이다. 그 후에 진입하는 친구 목록이나 채팅 목록 등의 화면 또한 하나의 액티비티이다.


이런 액티비티는 생명주기를 갖는다. 다시 카카오톡을 생각해 보자. 카카오톡을 사용하다가 유튜브 영상을 보기 위해 유튜브 앱을 실행하면 카카오톡 앱 화면은 더 이상 보이지 않고 유튜브 앱 화면이 보인다. 이때 카카오톡과 유튜브의 액티비티는 각자의 생명주기에 따라 호출되는 함수들이 있다.


생명주기를 쉽게 이해하려면 실제 화면에 표시 유무를 생각하면 된다. 먼저 최초로 앱을 실행하면 onCreate()가 호출되는데 이때 초기화 관련 작업을 하면 좋다. 다음으로 onStart()가 호출되는데 이 시점부터 사용자가 액티비티를 볼 수 있다. 그리고 액티비티가 실제 사용자와 상호작용이 가능한 포그라운드에 위치하면 onResume()이 호출된다. 이 상태를 액티비티가 실행 중인 것으로 본다.


반대로 액티비티가 실행 중인 상태에서 사용자와 상호작용이 불가능한 상태, 즉 포커스를 잃은 상태가 되면 onPause()가 호출된다. onStop()은 액티비티가 더 이상 보이지 않을 때 호출된다. 그리고 액티비티가 종료되거나 앱 프로세스 자체가 종료되면 onDestroy()가 호출된다.


이런 동작을 그림으로 나타내면 다음과 같다.


액티비티 생명주기


주의할 점은 불투명한 새로운 액티비티가 최상단으로 올라와서 기존 액티비티가 완전히 보이지 않게 되면 onPause()에 이어서 onStop()까지 바로 호출된다는 것이다. 생각해 보자. 불투명 새로운 액티비티가 최상단으로 올라오면 기존 액티비티는 사용자와 더 이상 상호작용을 할 수 없다. 포커스도 새로운 액티비티에 맞춰진다. 그렇기 때문에 onPause()가 호출될 것이다. 또한 불투명하기 때문에 기존 액티비티가 보이지 않으므로 onStop()까지 호출되는 것이다.


따라서 onPause()까지만 호출된 상태를 확인하고 싶다면 투명한 새로운 액티비티를 실행해야 한다. 이때도 실제로 투명하게 보여야만 되는 것은 아니다. 새로 호출되는 액티비티의 스타일 속성이 투명하다고 선언만 되어 있으면 해당 액티비티는 투명 액티비티라고 간주하고 onPause()까지만 호출된다. 예를 들면 다음과 같이 스타일을 주면 투명 액티비티로 간주된다. 하지만 실제 실행 시에는 백그라운드 색상이 투명하지 않기 때문에 불투명하게 보인다.



<style name="Theme.AppCompat.Translucent">
    <item name="android:windowIsTranslucent">true</item>
</style>



또한 다이얼로그를 띄워서 액티비티가 최상단이 아닌 상황에는 onPause()가 호출되어야 할 것 같지만 실제로는 그렇지 않다. 다이얼로그가 액티비티의 일부이기 때문이다. 즉, 새로운 액티비티가 최상단으로 온 상황이 아니기 때문이다. 따라서 아무런 함수가 호출되지 않는다.


이러한 생명주기 동작은 간단한 앱을 만들어 확인이 가능하다.


매니페스트에서 주목할 것은 SecondActivity에 적용된 style이다. SecondActivity는 투명한 액티비티이기 때문이다.


MainActivity는 버튼 2개로 구성되어 있고 각 생명주기에 호출되는 함수에 로그를 출력하도록 했다.



일단 앱을 최초로 실행하면 다음과 같은 로그를 확인할 수 있다.


D/LifeCycle: onCreate()

D/LifeCycle: onStart()

D/LifeCycle: onResume()



MainActivity


SecondActivity 버튼은 투명한 새로운 액티비티를 실행하는 버튼이다.

Show Dialog 버튼은 다이얼로그를 띄우는 버튼이다.


SecondActivity에텍스트뷰와 액티비티를 종료하는 버튼만 존재한다. MainActivity와 마찬가지로 각 생명주기에 호출되는 함수에 로그를 넣었다. MainActivity와 구분하기 위해서 TAG는 LifiCycle2로 지정했다.



SecondActivity를 호출하면 다음과 같이 보인다.


SecondActivity


이때는 투명한 액티비티가 호출되었기 때문에 onPause()까지만 호출된다. 따라서 로그를 보면 다음과 같다.


D/LifeCycle: onPause()

D/LifeCycle2: onCreate()

D/LifeCycle2: onStart()

D/LifeCycle2: onResume()


MainActivity는 onPause()까지 호출되었다. 완전히 보이지 않는 상태가 아니니 onStop()은 호출되지 않는다. SecondActivity가 표시되면서 해당 액티비티의 onCreate(), onStart(), onResume()이 호출되었다.


Finish 버튼을 눌러서 SecondActivity를 종료하면 다음과 같은 로그가 보인다.


D/LifeCycle2: onPause()

D/LifeCycle: onResume()

D/LifeCycle2: onStop()

D/LifeCycle2: onDestroy()


SecondActivity의 포커스가 MainActivity로 옮겨지고 MainActivity가 다시 보이면서 onResume()이 호출되었다. 그러면 더 이상 SecondActivity는 보이지 않으므로 onStop()이 호출되고 종료되면서 onDestroy()까지 호출되었다.


다이얼로그를 호출하면 생명주기에 어떠한 변화도 없다. 따라서 호출되는 함수가 없다. onPause()된 것이 아니기 때문에 확인이나 취소를 눌러서 MainActivity로 돌아가도 onResume()이 호출되지 않는다.



브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari