[Android] 안드로이드 개발 레벨업 교과서 정리 #1 액티비티


출처 : 안드로이드 개발 레벨업 교과서 34~40p

몰랐던 부분 정리하는 포스트!


# 액티비티를 이해하자

1. 액티비티란?

  • 사용자가 어떤 활동을 할 때 실행되는 애플리케이션의 컴포넌트
  • 액티비티에는 윈도우가 있고, 그 윈도우에 텍스트나 이미지를 표시해 사용자 조작에 반응할 수 있다.
  • UI가 없는 액티비티도 있지만 기본적으로 한 액티비티가 한 화면을 표시한다.


2. 액티비티의 수명주기를 이해하자

<표 2-1> 액티비티의 수명주기 종류

메서드명 시점 처리 예
onCreate 생성 시 초기화 처리와 뷰 생성(setContentView 호출) 등
onStart 비표시 시 통신이나 센서 처리 시작
onRestart 표시 시(재시작만) 보통 아무것도 하지 않음
onResume 최전면 표시 필요한 애니메이션 실행 등의 화면 갱신 처리
onPause 일부 표시(일시정지 상태) 애니메이션 등 화면 갱신 처리를 정지 또는 일시정지할 때 필요 없는 리소스를 해제하거나 필요한 데이터 저장
onStop 비표시(정지) 상태 통신이나 센서 처리 정지
onDestroy 폐기 시 필요 없는 리소스를 해제. 액티비티 참조는 모두 정리
  • 시스템 메모리가 모자랄 경우 시스템은 onStop, onDestroy를 콜백하지 않고 액티비티를 강제로 종료시켜 메모리를 확보할 때가 있다.
    • 이 경우 데이터를 영속적으로 보존하려면 액티비티가 일시정지 상태로 전환되는 onPause에서 이를 처리할 필요가 있다.
    • 졸업작품 프로젝트를 진행할때, 프래그먼트로부터 받은 데이터를 액티비티 변수에 담고있었는데, 실제로 위 경우를 겪은 사례가 있다. (정보를 날렸다)
  • 예를 들어, onCreate에서 뷰를 만들면 onDestroy에서 해제한다. 뷰는 액티비티가 폐기된 다음, GC에 의해 자동으로 메모리가 해제된다.
  • onStart에서 위치 정보 취득을 시작했다면 onStop에서 (만약 정보 취득을 완료하지 않았다면) 취득을 정지하는 식
  • onDestroy에서 액티비티가 폐기되면 GC가 메모리 영역에서 해제한다. 단, 액티비티 인스턴스가 다른 클래스에서 참조되고 있을 때는 폐기된 후에도 메모리에 남아 결국 메모리 누수가 발생한다.


디바이스 설정의 갱신 탐지

  • 액티비티는 디바이스 설정이 변경되면 기본적으로 시스템에서 현재 액티비티를 폐기하고 새로 생성한다.
    • 화면 방향 전환, 언어 설정 변경, USIM 교체에 따른 전화번호 변경 등
  • 액티비티를 재생성할 때는 현재 상태를 액티비티에 일시적으로 저장해서 이용할 수 있다.

    • 화면 방향 전환시에도 데이터를 유지시킬 수 있게 된다.
    • onSaveInstanceState, onRestoreInstance 의 파라미터 Bundle 객체로 저장, 불러오기가 가능하다.
      • 시스템의 임시 영역을 활용하고, 프로세스 간 통신(IPC)로 데이터를 주고받는다.
      • IPC는 서로의 자료형을 어떻게 주고받을지 정해 둘 필요가 있는데, 그 방법이 Parcelable 인터페이스로 정의돼 있다.
    • 저장할 수 있는 자료형은 primitive, List, Parcelable 객체이다.
  • onSaveInstanceState, onRestoreInstance 메서드는 사용자가 백버튼으로 액티비티를 명시적으로 폐기한 경우에는 호출되지 않는다.

  • 데이터를 저장하고 싶다면 onPause 시점에서 저장해 두면 된다.


3. 액티비티의 백스택을 이해하자

  • 새로운 액티비티가 시작되면 실행중이던 액티비티는 백스택에 들어간다.

  • 또한 시작된 액티비티는 태스크라는 그룹에 속한다. 이 항목은 안드로이드 OS 버전에 따라서도 미묘하게 동작이 달라 다 이해하기는 어려우므로, 아래 3가지만 기억하면 된다.

    1. 같은 앱에서 시작된 액티비티는 같은 백스택에 쌓인다
    2. taskAffinity의 속성에 따라 소속되는 태스크가 달라진다.
    3. launchMode에 따라 액티비티 생성의 여부, 새로운 태스크에 속하는 등 액티비티의 시작이 달라진다.


taskAffinity
  • 태스크 친화성이라는 의미지만, 대체로 ‘태스크 이름’으로 바꿔 읽는 것이 이해하기 쉽다.
  • taskAffinity가 지정되지 않은 경우 자기 앱의 패키지 이름이 태스크 이름이 된다.
  • 이를 설정하지 않으면 그 앱의 태스크이름은 모두 같아진다.
    • 태스크가 다르면, 백스택에 소속되는 그룹이 달라진다.


launchMode
launchMode 내용
standard 매번 액티비티의 인스턴스를 새로 생성한다. (기본값)
singleTop 같은 액티비티가 최상위에서 실행 중이면 액티비티를 생성하지 않고, 그 대신 최상위 인스턴스의 onNewIntent()를 호출한다.
singleTask 1개의 태스크에 인스턴스가 존재한다. 이미 같은 액티비티가 실행중이면 액티비티를 생성하지 않는다. (브라우저 앱이나 게임 앱 등 여러 액티비티를 만들고 싶지 않을 때 사용한다.)
singleInstance 1개의 태스크에 1개의 인스턴스만 존재한다. 다른 액티비티를 태스크에 포함하지 않는다. 이미 같은 액티비티가 실행중이면 액티비티를 생성하지 않는다. (기본적으로 잘 사용하지 않는다.)
  • 이 설정은 Manifest 에서 액티비티 속성으로 설정할 수 있고, android:taskAffinity=":someting" 라고 쓰면 된다.
    • 기본값이 지정된 액티비티들과, 위와같이 설정한 액티비티의 소속 그룹이 다른 것을 adb 로 확인해볼 수 있다.
    • 백스택 확인은 adb shell dumpsys activity activities 으로 하면 된다.
Share