세라쌤의 IT 튜토리얼

Activity와 Activity 생명주기 본문

Android

Activity와 Activity 생명주기

issell 2019. 3. 20. 04:51

어느 정도 res/layout의 xml을 사용하여 화면을 구성하는 방법에 대해서는 알았다.

하지만 xml문서는 View를 배치하고, 모양을 지정하는 등의 '정적 구조 표현'에만 관여하기 때문에 

View가 터치되었을 때 어떤 작업을 할 것인지, 혹은 기존의 텍스트를 다른 텍스트로 변경하거나 색상을 변경하는 등, 사용자와의 상호작용에 관한 작업이 필요하다면 xml로는 단연 부족하다.


이 경우 Activity와 같은 자바 클래스를 사용하여 구현해야 한다.


Activity 클래스


java.lang.Object
   ↳android.content.Context
    ↳android.content.ContextWrapper
     ↳android.view.ContextThemeWrapper
      ↳android.app.Activity

 


안드로이드 어플리케이션은 하나의 화면당 반드시 하나의 Activity가 적용된다. 웹사이트의 페이지와 같은 역할이라고 볼 수 있다.

물론 모든 Activity가 사용자에게 보여지는 것은 아니지만 대부분의 경우가 그렇다. 다음 예시를 보자.


위 어플리케이션은

게임시작 > 게임 진행 > 끝나면 > 기록화면 + 종료 버튼 식의 흐름으로 구성되어있다.

여기서 액티비티는 4개다. 


1. 게임 시작 버튼이 있는 액티비티

2. 게임을 진행하는 액티비티

3. 게임 오버 버튼이 있는 액티비티

4. 명예의 전당 리스트와 종료 버튼이 있는 액티비티 


왜 액티비티라고 하는지 감이 오는가?

이들은 단순히 사용자에게 화면을 보여주는 것이 전부가 아닌 각자 다른 활동을 한다. 

1번 액티비티는 사용자에게 '시작 버튼'을 보여주고 클릭이 되면 게임을 시작시키는 활동을 담당한다.

2번 액티비티는 사용자와 끊임없이 상호작용하며 사용자의 터치 좌표나 방식에 따라 화면을 재구성하고, 논리적으로 게임의 흐름을 제어하는 활동을 담당한다.

3번 액티비티는 사용자에게 '게임 오버 버튼'을 보여주고 클릭이 되면 명예의 전당으로 넘어가는 활동을 담당한다.

4번 액티비티는 DB에서 역대 기록을 조회하여 리스트형태로 사용자에게 보여주며, 어플리케이션을 종료하는 활동을 담당한다.


물론 '화면 == 액티비티'를 의미하는 것은 아니다.

화면은 액티비티가 아니더라도 구현할 수 있는 방법이 있고 (예. Fragment, Dialog) 

액티비티 또한 반드시 화면을 띄워한다는 법도 없다. (로직만 처리하는 액티비티일 수도 있다.)


Activity의 기본 형태

프로젝트를 생성하면 1개의 Main Activity 클래스가 생성되는데 

그 안을 살펴보면 다음의 코드가 자동으로 작성되어있다.

package com.sera.proj01gettingstarted;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

}

  } 




열심히 Activity 클래스에 대한 이야기를 했는데, 막상 이 녀석이 상속 받은 것은 AppCompatActivity 클래스다. 

AppCompatActivity 와 Activity는 비슷하지만 AppCompatActivity는 하위호환성을 위해 제작된 액티비티라 Activity를 구현할 때 

일반 Activity 클래스보다 AppCompatActivity를 상속하도록 권장하고 있다. ( 앞으로 AppCompatActivity, Activity 구분 없이 둘 다 Activity라고 하겠다. )


더 중요한 것은 그 안에 들어있는 onCreate() 메서드다. 

Override 애너테이션이 있는 것을 보아하니 누군가에게 상속을 받아온 것 같다! 

맞다! onCreate()은 Activity로부터 상속 받아 온 것이며, 액티비티가 시스템으로부터 호출 되어 생성되면 다음 단계에 자동으로 호출되는 메서드다. 참고로 화면이 있는 액티비티의 경우 setContentView()를 반드시 호출해야 한다. 화면을 설명한 layout xml 파일이 있다면 setContentView()의 인자로 넣는다. (단, xml은 반드시 res/layout에 있어야 한다.)


 주의:  onCreate() 오버라이드 시 super.onCreate(savedInstanceState); 부분은 생략하면 안되며 다른 코드 이전에 작성하여 가장     먼저 호출되도록 해야 한다. 액티비티를 생성하기 위한 사전 작업을 부모의 onCreate()이 하기 때문이다. 



그렇다면 savedInstanceState 매개변수는 무엇일까? 이것을 이해하려면 'Activity의 생명주기'에 대해 알아야 한다. 

이 부분은 굉장히 중요!!!하기 때문에 꼭 보고 넘어가야 한다.


Activity의 생명주기

안드로이드 디바이스는 데스크탑이나 랩탑에 비해 메모리 용량이 현저히 적고, 같은 애플리케이션이라 하더라도 액티비티끼리는 독립적인 행동 주체이기 때문에 액티비티 인스턴스는 시스템에 의해 생성되고 사라지는 것을 수시로 반복한다. 


Activity의 생명은 크게 3가지로 분류된다. 

entire lifetime : 액티비티가 처음 객체화 되었을 때부터 가비지 컬렉터에 의해 소멸될 때까지의 기간을 말한다. 액티비티 객체가 처음 생성되면 onCreate() 메서드가 호출되고 소멸되기 전에는 onDestroy()가 자동 호출되면서 객체를 정리한다. onCreate()에서는 주로 액티비티를 생성할 때 필요한 전반적인 설정 사항을 작업하고 onDestroy()에서는 남아있는 자원을 해제한다. 예를 들어 백그라운드 스레드를 통해 뒤에서 통신을 한다거나, 자원을 다운로드 혹은 업로드 해야 하는 액티비티의 경우 네트워크 스레드 호출은 onCreate()에, 스레드 종료는 Destroy()에 해야 정상적으로 스레드를 실행할 수 있다. 

visible lifetime : onStart() 호출 ~ onStop() 호출까지의 기간이다. 해당 액티비티가 액티비티 스택의 top에 위치하면 onStart()가 호출되며, top에서 벗어나면 onStop()이 호출된다. (액티비티 스택의 top에 위치한 액티비티는 곧 가장 위에 위치한 액티비티이며, 이는 화면에 보이는 액티비티를 뜻한다. 스택의 가장 위에 있는 액티비티만이 사용자와 상호작용 할 수 있다. ) onCreate()과 onDestroy()와는 다르게 onStart()/onStop()은 하나의 액티비티 객체가 여러 번 호출할 수 있다. 하지만 onStart()가 실행되는 시점에는 아직 사용자와 상호작용할 UI는 활성화되지 않는다. 

foreground lifetime : onResume() 부터 onPause()까지의 기간을 의미하며 이는 즉 화면에 노출되는 기간을 말한다. (예. 디바이스가 절전모드가 되면 onPause()가 호출되고, 다시 켜질 때는 onResume()이 호출) 다른 기간보다 이 기간이 제일 빈번히 갱신되기때문에 onResume()와 onPause()의 내용은 가벼워야 한다. 

MethodDescriptionKillable?Next
onCreate()

Activity가 생성될 때 최초로 호출된다. 화면을 생성하거나, 데이터를 바인딩하는 등의 정적 설정을 여기서 수행하도록 한다. 해당 Activity가 이전에 호출되었다가 재생성되는 경우에는 이전에 설정되었던 Bundle이 onCreate()의 인자로 들어온다. 이후 onStart()가 호출된다.

NoonStart()
    onRestart()

Activity가 Stop 상태였다가 재개되는 경우 호출된다. 이후 onStart()가 호출된다.

NoonStart()
onStart()

Activity가 사용자의 화면에 나타나야하는 경우 호출된다. 화면 스택에서 벗어나면 onStop()이 호출되지만 벗어나지 않은 경우 onResume()이 호출된다. 

NoonResume()or onStop()
    onResume()

Activity Stack의 top에 위치하며, onResume()이 호출되어야 사용자와 상호작용할 수 있다. 

NoonPause()
onPause()

시스템이 이전 액티비티를 실행할 때 호출된다. 이 메소드에는 액티비티의 데이터를 최종 저장하거나, 진행 중이었던 애니메이션을 멈춰서 자원이 누수되지 않도록 한다. 이 메서드가 실행되는 동안 다음 액티비티는 resume 될 수 없기 때문에 가벼운 업무만 수행하도록 한다. onPause() 이후 해당 액티비티가 다시 화면의 맨 앞에 위치할 경우 onResume()이, 아닐 경우 onStop()이 이어서 호출된다. 

Pre-Build.VERSION_CODES.HONEYCOMBonResume()or
onStop()
onStop()

해당 Activity가 Activity Stack의 top에서 밀려날 때 호출된다. Activity가 다시 top이 될 때는 onRestart()가, stack 대기열에서 완전히 없어질 땐 onDestroy()가 호출된다.

Yes

onRestart()or
onDestroy()
onDestroy()

Activity 객체가 해제되지 직전 호출된다. 액티비티가 finish() 메서드를 통해 종료되거나, 시스템의 판단하에 자동으로 액티비티를 해제하는 두 경우 모두에 호출되는데, 만약 두 경우를 구분짓고 싶다면 메서드 내부에 isFinishing() 메서드를 추가로 호출하여 분기 처리 할 수 있다.

Yes










'Android' 카테고리의 다른 글

android:layout_width와 android:layout_height  (0) 2019.03.25
TextView  (0) 2019.03.25
Widgets  (0) 2019.03.17
Frame Layout  (0) 2019.03.17
Relative Layout  (0) 2019.03.15
Comments