1. 개요
다른 액티비티로 전환시 기존의 액티비티는 액티비티 스택에 깔리고 새로운 화면이 추가된다. 백버튼을 눌렀을 경우 액티비티 스택에 있던 액티비티들은 다시 보여진다.
액티비티가 화면에 보이거나(focus) 보이지 않고 가려졌을 때 처리를 해야할 필요가 있다. 예를 들면, 작성하던 문서 내용을 저장하거나 게임 내역을 기억하고있는 등의 경우이다.
이렇게, 액티비티의 상태가 변할 때마다 안드로이드 시스템은 각 상황에 맞는 메소드를 자동으로 호출해주는 '액티비티의 생명주기'가 있다. 그래서 자동으로 호출되는 이 메소드들을 Override해서 각 상태에 따라 제어할 수 있다.
2. 생명주기
액티비티는 안드로이드 시스템에 관리되기 때문에 언제라도 중지되거나 메모리에서 삭제될 수 있다. 예를 들면, 전화가 오는 경우 통화를 우선으로 처리해야 하기 때문에 메모리가 모자랄 경우 실행중이던 앱을 임의로 종료시켜버린다. (아예 종료시켜버리는 것이 아닌 프로세스를 kill한다.) 이러한 처리 과정은 아무런 예고없이 이뤄지는데, 이를 대비해 사용자는 각 상태에 맞게 기능이 동작할 수 있도록 처리해주어야한다.
수명주기는 화면의 상태에 따라 달라지는데, 각각의 상태에 따라 자동으로 호출되는 메소드가 다르다.
맨 처음 앱이 실행되고 첫 화면이 그려지면 onCreate() - onStart() - onResume() 가 차례로 호출된다.
화면이 사라지는 과정은 onPause() - onStop() - onDestroy() 가 차례로 호출된다.
위 과정을 간단하게 표현한 그림은 아래와 같다.
출처 : 부스트코스 강의자료
onPause() 메소드는 화면이 눈에서 보이지 않게 될 때 중지되는 시점에 바로 호출되므로, 일반적으로 onPause()에서 필요한 데이터를 저장한다. (간단하게 SharedPreferences, 다른 방법으로는 onSaveInstanceState를 이용할 수 있다.)
* 참고 : on으로 시작하는 이름으로 구현된 메소드들은 대부분 콜백메소드로, 상태에 맞춰 자동으로 호출된다.
- 최초 실행
onCreate()
onStart()
onResume()
- 홈버튼
onPause()
onStop()
- 홈버튼에서 다시 켜기(화면 꺼진 상태에서 켜기)
onStart()
onResume()
- 가로모드로 전환
onPause()
onStop()
onDestroy()
onCreate()
onStart()
onResume()
위는 직접 override 하여 테스트해본 결과이다. (restart는 까먹어서 빠졌다.)
신기한 부분은 화면 전환이다. onDestroy()는 액티비티가 종료될 때 호출되는 메소드인데 실행되다니 놀랐다. (실제로 개발하다가 이 현상을 보게되어 난항을 겪었었다. 해결한 방법은 onSaveInstanceState를 사용했다.) 자동으로 화면 전환을 하는 어플의 경우에는 꼭 생명주기를 기억해야할 것이다....(액티비티에 입력했던 데이터들이 날아가버린다)
그리고 현재 개발중인 프로젝트는 실행시 상당한 메모리를 차지하는데, 이 또한 생명주기에 영향이 미쳤다. 위에서 언급한 바와 첫번째 생명주기 그래프 사진에서 볼 수 있듯이, App process가 죽임을 당한다(?). 그래서 프래그먼트로부터 전송받은 데이터들이 증발해버리는 것을 보고 멘붕이었다. 아직 해결하지 않았으므로, 해결한 후 나중에 정리하도록 할 것이다.
3. 예제 코드
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "onCreate 호출됨.", Toast.LENGTH_LONG).show();
}
@Override
protected void onStart() {
super.onStart();
Toast.makeText(this, "onStart 호출됨.", Toast.LENGTH_LONG).show();
}
@Override
protected void onStop() {
super.onStop();
Toast.makeText(this, "onStop 호출됨.", Toast.LENGTH_LONG).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
Toast.makeText(this, "onDestroy 호출됨.", Toast.LENGTH_LONG).show();
}
@Override
protected void onPause() {
super.onPause();
Toast.makeText(this, "onPause 호출됨.", Toast.LENGTH_LONG).show();
}
@Override
protected void onResume() {
super.onResume();
Toast.makeText(this, "onResume 호출됨.", Toast.LENGTH_LONG).show();
}
Toast 메시지를 띄우는 것 보다는 Log.d 를 이용하는 것이 가독성이 더 좋을 것이다. 그리고 onRestart()도 넣어야하고...
* 참고 : Override는 Ctrl+o 를 누르면 바로 나온다. (Android studio)
Log.d(TAG, "onDestroy() 호출됨,")
(TAG 는 String 상수)
'Android > Basic' 카테고리의 다른 글
[Android] Time to String 및 시간순으로 정렬하기 (0) | 2018.06.22 |
---|---|
[Android] Action Bar (0) | 2018.05.27 |
[Android] startActivityForResult() 활용 예제 (0) | 2018.05.18 |
[Android] Permission (0) | 2018.05.17 |
[Android] Broadcast receiver 예제 (6) | 2018.05.16 |