액티비티는 안드로이드의 4대 컴포넌트 중의 하나로 사용자에게 화면을 제공하는 가장 기본이 되는 구성요소이다
액티비티는 생명 주기 전체 기간에 걸쳐서 상태가 계속 변화한다. 사용자가 앱에서 어떤 동작을 취하면 앱 안에서 하나의 화면을 담당해서 제공하는 액티비티는 상태가 변한다. 예를 들어서, 사용자가 다른 화면으로 이동하는 동작을 취했다면 이전의 화면은 보이지 않은 상태가 되고, 다른 화면은 사용자에게 보이기 위한 작업을 마치고 사용자에게 보여지는 상태가 된다. 이렇듯, 액티비티는 지속적으로 상태가 변하는데, 상태에 맞는 작업을 처리해야 한다. 그렇게 해야 앱이 비정상적인 종료가 발생하지 않거나 리소스를 많이 잡아 먹어 제대로 동작하지 않는 일이 발생하지 않는다. 이를 위해서 액태비티의 생명주기의 각 상태마다 호출되어서 작업을 처리하는 콜백 메서드가 존재한다.
액티비티의 생명 주기 콜백 메서드는 다음과 같다.
onCreate()
onStart()
onResume()
onPause()
onStop()
onRestart()
onDestroy()
시스템이 액티비티를 처음 실행시킬 때 호출되는 메서드이며 전체 생명 주기 동안 한 번만 호출된다. 구현 시 액티비티에 필요한 구성요소를 초기화해야 한다. 화면을 제공하는 역할을 담당하는 액티비티에게 가장 중요한 구성요소인 뷰를 생성해서 필요 시에 데이터를 데이터 목록에 결합해야 한다.
onCreate() 함수가 사용자에게 화면(레이아웃)을 보여줄 준비를 마치고, 종료하게 되면 호출되는 메서드이다. onStart() 함수가 호출되면 액티비티가 사용자에게 정상적으로 뷰를 제공하여 확인할 수 있도록 한다. 또한 onStart() 함수는 포그라운드에서 사용자와 상호작용을 할 수 있는 작업을 준비한다. onStart() 함수는 빠르게 작업을 마치고 종료되며, 곧바로 onResume() 콜백 메서드가 호출된다.
onResume() 함수가 호출되었을 때 사용자와 상호작용을 할 수 있게 된다. 다른 화면으로 전환되거나 기기의 화면을 끄는 등의 이벤트가 발생하지 않는 동안에는 resume 상태에 머무르게 된다. 만약 다른 화면으로 전환하는 이벤트가 발생하게 되면 액티비티는 resume 상태에서 벗어나 onPause() 메서드를 호출하게 된다.
액티비티가 담당하는 화면을 사용자가 떠났을 때 처음으로 호출되는 메서드이다. 즉, 이 onPause() 함수가 호출되면 액티비티가 포그라운드에 있지 않다는 의미이다. 액티비티가 포그라운드에 있지 않기 때문에 액티비티가 굳이 가지고 있지 않아도 되는 리소스를 onPause() 메서드에서 해제해도 된다. 단, onPause() 함수는 아주 잠깐 실행되기 때문에 오버헤드가 큰 작업을 수행하기에는 무리가 있다. 액티비티가 다시 시작되면 pause상태에 있던 액티비티는 다시 onResume() 메서드를 통해서 resume 상태로 돌아오게 된다.
onStop() 메서드는 사용자가 화면을 완전히 떠나 더 이상 액티비티가 담당하는 화면이 보이지 않을 때 호출되는 메서드이다. onStop() 메서드에서 화면이 보이지 않을 동안 필요하지 않은 리소스를 해제하거나 조정할 필요가 있다. onStop()이 호출된 상태, 즉 Stop 상태에 들어가면 액티비티 객체는 메모리에 머무르게 되고 액티비티가 다시 재개되면 정보를 다시 호출하게 된다. stop 상태에서 액티비티가 다시 시작되면 onRestart() 메서드를 호출하게 된다.
onPause() 메서드는 아직 사용자에게 액티비티가 담당하는 화면이 보이지만 포커스가 다른 액티비티에게 가 있는 경우에 호출되고, onStop() 메서드는 화면이 아예 보이지 않은 상태에서 호출된다. onPause()는 포커스 상실 상태, onStop()는 백그라운드 상태로 이해하면 좋을 것 같다.
onRestart() 메서드는 stop상태에서 다시 액티비티를 재개하는 상황에서 호출되는 메서드이다. 즉, onRestart() 메서드는 onStop() 메서드가 호출된 이후에 호출되는 메서드이다. onRestart() 메서드는 호출된 이후에 onStart() 함수가 다시 호출될 것이다.
onDestroy() 메서드는 액티비티가 완전히 소멸하기 전에 호출되는 메서드이다. 사용자가 완전히 앱을 종료하거나, 액티비티 내부에 있는 finish() 함수가 호출되거나, 기기회전과 같은 구성 변경을 하는 등의 경우에 destroy 상태가 된다. onDestroy() 메서드가 호출되고 나면 액티비티는 완전히 소멸될 것이기 때문에 onStop() 메서드에서 해제하지 않은 리소스들에 대해서 모두 해제를 해줘야 한다.
특정한 이벤트에 의해서 액티비티가 상태가 변함에 따라, 앱에서 보여주고 있는 데이터가 갑자기 초기값으로 변하는 원치 않은 경우가 발생할 수 있다. 예를 들어, 앱의 데이터가 사용자의 동작으로 적절히 잘 변경되고 있었는데, 기기 회전으로 인해 onDestroy() 메서드가 호출되고, 리소스를 정리하는 과정에서 사용자가 건드리고 있는 데이터까지 날라가서 다시 액티비티가 재개되었을 때는 초기값으로 변경되는 케이스가 발생한다. 이는 액티비티의 생명주기를 고려하지 않아서 생긴 문제이다.
즉, 리소스를 효율적으로 관리하기 위해서는 액티비티의 생명주기를 정확히 알고 있는 상태에서 각 상태에 맞게 리소스를 적절히 관리해줘야 한다.