'activity lifecycle'에 해당되는 글 4건

  1. 2013.09.30 Android Activity State
  2. 2013.09.30 Stopping/Restarting Android Activity
  3. 2013.09.29 Pausing/Resuming Android Activity
  4. 2013.09.29 Creating/Destroying Android Activity
Programming/Android2013. 9. 30. 22:04

Managing the Activity Lifecycle (4/4)


액티비티 다시 생성(Recreating an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/recreating.html


백버튼이 눌려지거나 finish() 메소드가 호출되는 액티비티가 소멸되는 몇몇 시나리오가 있다. 또 시스템에서 화면 전면의 액티비티가 많은 메모리를 필요로 하거나 하는 경우 액티비티를 소멸시킬 수 있다.


하지만 이렇게 시스템이 액티비티 객체를 소멸시켰을 때 사용자가 백버튼을 이용하여 다시 그 액티비티로 복기하려 할 때 소멸된 액티비티를 다시 불러올 수 있다. 이는 그 액티비티를 인스턴스화 하고 번들 객체에 key-value 짝으로 저장되어 있는 데이터를 가져온다. 이렇게 저장된 데이터를 인스턴스 상태(instance state)라고 한다.


기본적으로 시스템은 번들 인스턴스로 액티비티에 레이아웃에있는 View 객체 같은 것을 저장한다. 그래서 액티비티 인스턴스가 소멸되고 재생성될때도 그전의 상황을 재현할 수 있다. 하지만 이런 다시 재생성될때 같이 돌아오고 싶은 더 많은 정보들이 있다.(멤버 변수 같은)


액티비티 상태 저장(Save Your Activity State)

만약 더 많은 정보를 저장하려면 onSaveInstanceState() 콜백 메소드를 오버라이드 해야한다. 이때 Bundle 객체를 인자로 받고 이곳에 저장하고 싶은것을 Key-Value로 저장하면 된다. 이렇게 예상 밖에 액티비티가 소멸됐다가 나중에 다시 재생성될때 onRestoreInstanceState()와 onCreate() 두 메소드에 인자로 Bunde 객체를 보내 이곳에서 위에서 저장한 정보를 불러올 수 있다.

한마디로 무조건 일어버리면 안돼는 정보는 Bundle에 저장해라.(물론 View의 스크롤 포지션이나 에디트 텍스트의 문장 같은 자동으로 저장되는 것이 있다.)


액티비티 상태 다시 불러오기(Restore Your Activity State)

위에서 Bundle객체를 가지고 오는 법이 onCreate()와 onRestoreInstanceState() 두가지 방법이 있다고 했는데 onCreate() 의 경우 Bundle객체가 null일 수 있기 때문에 if 문으로 null 체크를 해주어야 하지만 onRestoreInstanceState()의 경우 번들 객체가 있을 때만 메소드를 콜백하기 때문에 null 체크를 해줄 필요가 없다.

Posted by Brian B. Lee
Programming/Android2013. 9. 30. 21:03

Managing the Activity Lifecycle (3/4)


액티비티의 멈춤과 재시작(Stopping and Restarting an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/stopping.html


- 사용자가 앱 사용중 화면 전면에서 사라진후 다시 홈 스크린에서 이 앱을 실행시키거나 대체된 앱에서 다시 본 앱으로 돌아왔을 때, 앱티비티가 다시 실행된다.

- 액티비티에서 다른 액티비티를 실행시켰을때 그 전 액티비티는 멈춰진다. 만약 사용자가 뒤로가기 버튼을 눌러도 첫번째 액티비티는 다시 시작된다.

- 앱을 사용할때 전화를 받았을 때도 액티비티는 멈춰진다.


액티비티는 멈춤과 재시작을 위해 onStop()과 onRestart() 메소드를 제공한다. 이는 Paused 상태와 다르게 화면에서 액티비티가 완전히 사라진다.


Note. 시스템이 스톱될때 시스템 메모리안에 액티비티 인스턴스를 저장하기 때문에 onStop(), onRestart() 심지어 onStart() 메소드를 구현할 필요가 없을 수 있다. 그래서 심플한 관계를 가지고 있는 액티비티간의 동작은 onPause() 메소드를 이용한 시스템 리소스를 컨트롤 하는 작업만이 필요할 수 도있다.


액티비티 정지(Stop Your Activity)

스톱이 되었을때 더이상 사용자에게 보이지 않기 때문에 대부분의 리소스를 릴리즈 해야한다. 만약 시스템 메모리 되찾기가 필요하면 시스템은 이 인스턴스를 재거되거나 심지어 필요에따라 아무 알람없이 onDestory() 콜백을 호출하여 종료시킬 수 있다. 그래서 메모리 누수를 막기위해 onStop() 메소드에서 리소스를 릴리즈 시켜줘야 한다.


액티비티가 스탑될 때, 액티비티 객체는 메모리에 상주 데이터로 남게 되고 액티비티 재개에서 리콜되어 진다. 그래서 거의 대부분의 경우 재초기화의 필요성이 없다.


액티비티의 시작과 재시작(Start/Restart Your Activity)

액티비티가 화면에 전면에 다시 나타날때 onRestrt()메소드가 실행된다. 그리고 바로 시스템은 onStart() 메소드를 호출하고 이 메소드는 액티비티가 화면에 보일때 마다 이루어진다. 하지만 onRestart() 메소드는 Stopped 상황에서 resume 될때만 호출된다.


보통 onRestart() 메소드는 사용되지 않고 특정 상황에서 리소스를 릴리즈 하기위해서만 사용된다. 그리고 보통은 onStart()와 onStop()를 한쌍으로 본다.


결국 정리하면 

onStart()는 

1. 처음 앱이 시작할 때 

2. 액티비티가 stopped 됐다 Resumed 로 돌아갈때

이렇게 두가지 경우에서 실행되고


onResume()는 

1. 처음 앱이 시작할 때 

2. Pused 됐다 돌아올 때 

3. stopped 됐다 돌아갈 때

와 같이 액티비티가 화면의 전면에 나타날때는 모두 실행된다.


onRestart()는 

1. Stopped에서 Resumed로 갈때 한번만 실행된다.


onPause()는

1. Pauee() 만 될때 (전화가 오거나 알람이 울어 포커스를 잃었을 때)

2. Stopped 상태가 되는 과정에 실행

3. Destroyed 상태가 될는 과정에 실행

그러니까 Resumed 상황에서 변경되면 모두 발생


onStop()는

1. Stopped 상태로 변할 때

2. Destroyed 상태로 변할 때


onDestroy()

1. Destroyed 상태로 변할 때 한번


상태가 변하면서 거쳐가는 과정이 있기 때문에 중간 중간 메모리 관리하면 된다. 그리고 결국 액티브 인스턴스가 Destroyed 상태로 변하기 전까지 메모리로 보관대기 때문에 크게 객체를 따로 보관할 필요는 없지만 객체에서 생성한 스레드 같은 것은 잘 관리 해주어야 그렇지 않으면 시스템에서 예고 없이 앱을 종료시킬 수 있다.


다음에는 Managing The Activity Lifecycle 의 마지막으로 위와 같이 잘 작동하다 시스템이 맘대로 지가 메모리가 모잘라 Stopeed 상태인 내 앱을 죽여버렸을 때 어떻게 데이터를 유지할 지 보겠다.

Posted by Brian B. Lee
Programming/Android2013. 9. 29. 22:08

Managing the Activity Lifecycle (2/4)


액티비티의 멈춤과 재개(Pausing and Resuming an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/pausing.html#Resume


앱이 실행되는 동안 다른 비주얼 컨포넌트로 가리워 질 수 있다 이때  Puse 동작이 이루어 진다. 이때 반투명 액티비티가 실행되거나 부분적으로 액티비티가 가리워 진다. 


하지만 모두 가려졌을 때 이것은 stoped 상태가 된다.


처음 액티비티가 Paused 상태가 되면 onPause() 메서드를 실행시킨다. 이때 모든 실행은 더이상 진행할 수 없게 되고 사용자 진행을 위해 어느 정보들은  저장된다. 그리고 다시 사용자가 이 액티비티로 돌아올 때 onResume() 메소드가 실행 된다.


액티비티 중지 (Pause Your Activity)

- 애니메이션을 중지하거나 CPU를 소모하는 동작들을 중지

- 오직 사용자가 변화를 저장되어지길 기대하는경우에만 저장되지 않은 변화를 관리한다. (이메일 드레프트 같은)

- 사용자가 필요로 하지 않은 브로드케스트 리씨버나 센서(GPS같은) 사용같은 베터리 라이프에 영향을 미치는 시스템 자원들을 릴리즈한다.


보통 onPause() 메소드를 사용하여 연구 보관 저장장치에 사용자 변화(개인 정보가 입력되었을 때)를 저장하지 않는다. 하지만 특정 정보(이메일 드레프트 같은)의 경우 사용자 기대에 의해 저장되어 질 수 있다. 물론 CPU에 부화를 주는 데이터베이스 쓰기 작업 같은 경우 다음 액티비티의 트렌젝션 화면이 느려질 수 있다 이런경우를 피해야겠다.


Note: 액티비티가 멈출때 액티비티 인스턴스의 메모리 정보는 지켜지면 재개될때 리콜된다.  그래서 다시 컨포넌트를 재초기화 할 필요는 없다.



액티비티 재개(Resume Your Activity)

액티비티가 Pause 되었다 다시 재개되면 onResume() 메소드를 호출 한다.


처음 액티비티가 생성될때를 포함해 액티비티가 전면에 실행 될때 마다 이 메소드는 호출 된다는 점을 인지해야한다. 그래서 onPause(), onResume() 메소드 호출 시 상황에 맞는 초기화를 잘 해주어야 한다. 


onResume()과 onPause() 메소드는 한 쌍이기 때문에 onPause()에서 camera.release() 되면 onResume()의 경우 initializeCamera()해주는 것과 같이 관리 되어야한다. 

Posted by Brian B. Lee
Programming/Android2013. 9. 29. 21:17

Managing the Activity Lifecycle (1/4)


액티비티의 시작(Starting an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/starting.html


main() 메서드로 시작하는 다른 프로그램과 달리 안드로이드는 Activity의 인스턴스의 콜백으로 시스템이 시작한다. 

참고: 콜백? vs 호출?

콜백함수와 함수 호출의 차이는 제어권에 있다

호출자가 -> 피호출자 호출(일반적인 함수 흐름)

피호출자 -> 호출자 호출(콜백의 함수 흐름)

즉, 안드로이드에서 콜백함수를 실행시켜줘야 앱이 동작한다는 거다.


라이프사이클 콜백의 이해(Understand the Lifecycle Callbacks)



그림 1. Lifecycle Callback Status


액티비티의 복잡성에따라 모든 인스턴스를 라이프사이클을 정의해 줄 필요는 없지만 사용자의 기대치에는 부합해야한다. 라이프 사이클의 메서드를 정의함으로써 다음과 같은 올바른 행동을 정의할 수 있을것이다.

- 앱을 사용할 때 전화를 받거나 다른 앱으로 변경시 액의 문제를 방지할 수 있다.

- 사용자가 앱을 상요하지 않을 때, 시스템 자원을 소비를 피할 수 있다.

- 앱에서 빠져나가거나 앱의 마지막 상황으로 돌아갈 때, 사용자의 진행사항을 일지 않을 수 있다. 

- 화면의 변경에서 사용자의 진행사항이나 문제를 피할 수 있다.


그림 1.에서 다른 많은 상황들이 있지만 정적인 상황은 결국 세가지 밖에 없다.

1. 재점유된(Resumed): 액티비티가 화면 전경에 보이고 사용자가 사용할 수 있다. (running이라고도 한다)

2. 중지된(Paused): 액티비티가 다른 액티비티로부터 숨김을 당했을 때이다 - 화면의 전경에 있는 다른 앱이 반투명이거나 전체화면을 모두 점유하지 못할 때이다. 이 상황에서는 사용자의 입력을 받을 수 없고 어느 코드도 실행될 수 없다.

3. 멈춘(Stopped): 액티비티가 완전히 가려졌거나 화면에 전혀 보이지 않을 때이다. 백그라운에서 돌아가게 되고 이 멈춤 중에는 액티비티의 인스턴스와 모든 멤버 변수같은 상황 정보 보유되나 코드를 실행시킬 수는 없다.


앱 런처 액티비티의 명세(Specify Your App's Launcher Activity)

홈 스크린에서 앱 아이콘을 실행하면 런처(or 메인)로 앱티비티로 지정된 액티비티의 onCreate() 메소드가 실행시된다.(메니페스트 파일에 명시)


새로운 인스턴스 생성(Create a New Instance)

액티비티가 실행되면 새로운 Activity 인스턴스의 onCreate() 메소드를 실행시키고 사용자 인터페이스(XML 레이아웃 파일)를 정의하거나 맴버 변수 정의 혹은 UI의 환경설정 등을 할 수 있다.

onCreate() 메소드가 실행되고 바로 onStart() 메소드가 실행되어 화면이 보이게 되지만 또 바로 onResume()로를 호출되어 Resumed 상황이 되기 때문에 다른 상황 변화에 대해서 Started 상황이 컨트롤 할 필요는 없다.


액티비티 소멸(Destroy the Activity)

대부분의 경우 onDestroy() 메소드를 사용할 일이 없지만(자동으로 메모리 관리) 만약 액티비티가 onCreate() 메소드에서 백그라운드 스레드를 만들거나 롱런 자원을 가지고 있다면 이 자원들이 메모리 누수를 일이킬 수 있음으로 onDestroy() 메소드를 통해 이 자원들을 닫아줘야 한다.


그림 1에서 와 같이 onDestory() 메서드 호출 전 onPause(), onStop()가 먼저 이루어진다. 하지만 예외가 하나 이다. onCreate() 메소드에서 finish() 메서드를 콜했을 때이다. 일시적 결정권자로써 액티비티가 다른 액티비티를 실행시켰을 때 finish()를 호출할 수 있는데 이는 중간 과정 없이 onDestory() 메서드를 호출 한다.

Posted by Brian B. Lee