[Android Codelab] DessertClicker - Logcat

jihyo·2022년 2월 11일
0

Codelab

목록 보기
2/2

DessertClicker 소개

사용자가 화면에서 디저트를 탭할 때마다 앱이 구매를 한다. 앱은 구매한 디저트 수와 사용자가 소비한 총 금액에 관해 레이아웃에서 값을 업데이트한다. 프로젝트 주소

DessertClicker 개요

이번 코드랩에서는 크게 4가지 작업을 해볼 것이다.

  • Logcat에 표시되는 로깅 정보를 추가한다.
  • 수명 주기 콜백 메서드를 재정의하고 Activity 상태의 변경사항을 기록한다.
  • 앱을 실행하고 Activity가 시작, 중지, 재개될 때 표시되는 로깅 정보를 기록한다.
  • onSaveInstanceState() 메서드를 구현하여 기기 설정이 변경되면 손실될 수 있는 앱 데이터를 유지한다. 앱이 다시 시작될 때 이 데이터를 복원하는 코드를 추가한다.

Activity Lifecycle

모든 Activity는 Lifecycle(생명주기)를 가진다. 생물이 태어나고 죽는 것처럼 Activity도 생성되고 종료된다. 사용자가 앱을 시작Activity간 이동 또는 앱 안팎으로 이동할 때 Activity의 상태를 변경한다.

동작을 변경하거나 Activity 생명주기 상태가 변경될 때 코드를 실행하는 경우가 많다. 따라서 Activity 클래스 자체와 Activity의 모든 서브클래스(ex: AppCompatActivity)는 일련의 생명주기 콜백 메서드를 구현한다. Android에서는 Activity가 다른 상태로 이동할 때 이러한 콜백을 호출하고 개발자는 이러한 메서드를 자체 Activity에서 재정의하여 생명주기 상태 변경에 응답해 작업을 실행할 수 있다. 아래 그림은 재정의가 가능한 콜백과 함께 생명주기 상태를 보여줍니다.

콜백이 호출되는 시점과 각 콜백 메서드에서 할 작업을 알아야 한다.

1단계: onCreate() 메서드 확인 및 로깅 추가

Android 생명주기를 파악하려면 생명주기 메서드가 호출되는 시점을 알아야 한다. 그러면 문제가 발생하는 위치를 파악할 수 있다.

로깅을 사용하면 앱이 실행되는 동안 짧은 메시지를 콘솔에 쓸 수 있고 다양한 콜백이 트리거될 때를 표시할 수 있다.

  1. Dessert Clicker 앱을 실행하고 사진을 여러 번 탭을 하여 Desserts Sold의 값과 총 달러 금액이 어떻게 변경되는지 확인한다.

  2. MainActivity.kt를 열고 이 활동의 onCreate() 메서드를 확인합니다.

모든 활동에서 구현해야 하는 메서드가 바로 onCreate() 이다.

onCreate() 메서드에서 Activity의 일회성 초기화를 실행한다. 예를 들어, 레이아웃 확장, 클릭 리스너를 정의하거나 뷰 바인딩을 설정한다.

onCreate() 메서드를 재정의할 때 슈퍼클래스 구현을 호출하여 Activity 생성을 완료해야 하므로 활동 내에서 super.onCreate()를 즉시 호출해야 한다. 다른 생명주기 콜백 메서드의 경우에도 마찬가지다.

  1. onCreate() 메서드에서 super.onCreate() 호출한 다음 로그를 작성한다.

Log 클래스는 Logcat에 메시지를 쓴다. Logcat은 메시지를 기록하는 콘솔로 Log.d() 메서드나 기타 Log 클래스 메서드를 사용하여 로그에 명시적으로 전송하는 메시지를 비롯하여 앱에 관한 Android의 메시지가 표시된다.

Log.d("MainActivity", "onCreate Called")

위 코드는 세 부분으로 나뉘는데,

  • Log.d() : 로그 메시지의 우선순위. 메시지의 중요도를 나타내는 디버그 메시지로, Log 클래스의 다른 메서드에는 정보 메시지의 경우 Log.i()나 오류 메시지의 경우 Log.e(), 경고 메시지의 경우 Log.w(), 자세한 메시지의 경우 Log.v()가 있다.

  • "MainActivity" : 로그 태그(첫 번째 매개변수). 태그는 Logcat에서 로그 메시지를 더 쉽게 찾을 수 있도록 한다. 태그는 보통 클래스 이름을 사용한다.

  • onCreated called : 실제 로그 메시지(두 번째 매개변수).

클래스에서 TAG 상수를 선언하는 것이 좋다.

const val TAG = "MainActivity"

아래처럼 후속 로그 메서드 호출에서도 사용한다.

Log.d(TAG, "onCreate Called")

이제 하단에서 Logcat을 열어 D/MainActivity를 검색하면

Logcat

이렇게 검색을 통해 필요한 메시지를 확인할 수 있다. 앱이 실행되고 Activity가 생성됨에 따라 아까 추가한 Log 메서드에 의해 메시지가 출력되었다. (검색할 때 D/를 추가하면 디버그 메시지를 의미한다.)

2단계: onStart() 메서드 구현

onStart() 생명주기 메서드는 onCreate() 직후에 호출된다. onStart()가 실행되면 Activity가 화면에 표시된다. Activity를 초기화하는 데 한 번만 호출되는 onCreate()와 달리 onStart()는 Activity의 생명주기에서 여러 번 호출될 수 있다.

onStart

onStart()는 상응하는 onStop() 생명주기 메서드와 페어링된다. 사용자가 앱을 시작한 후 기기 홈 화면으로 돌아오면 Activity가 중지되고 더 이상 화면에 표시되지 않는다.

  1. MainActivity 클래스 안에서 onStart()를 override 한다.

  2. 클래스 선언 class MainActivity. 위에 있는 MainActivity.kt의 최상위 수준에서 상수를 추가한다.

const val TAG = "MainActivity"
  1. onStart() 메서드에 로그 메시지 코드를 추가한다.
override fun onStart() {
   super.onStart()
   Log.d(TAG, "onStart Called")
}
  1. DessertClicker 앱을 컴파일하고 실행한 다음 Logcat 창을 연다. 검색창에 D/MainActivity를 입력하여 찾는다. onCreate() 메서드와 onStart() 메서드가 모두 차례로 호출된 후 Activity가 화면에 표시된다.

  2. 기기에서 홈 버튼을 누른 다음 최근 사용한 Activity로 돌아가고 Activity는 모두 동일한 값으로 중단된 지점에서 다시 시작되고 onStart()는 Logcat에 두 번째로 기록된다. onCreate() 메서드는 일반적으로 다시 호출되지 않는다.

onStart Logcat

3단계: 더 많은 로그 추가

  1. MainActivity에서 나머지 생명주기 메서드를 재정의하고 메서드마다 로그 구문을 추가한다.
override fun onResume() {
   super.onResume()
   Log.d(TAG, "onResume Called")
}

override fun onPause() {
   super.onPause()
   Log.d(TAG, "onPause Called")
}

override fun onStop() {
   super.onStop()
   Log.d(TAG, "onStop Called")
}

override fun onDestroy() {
   super.onDestroy()
   Log.d(TAG, "onDestroy Called")
}

override fun onRestart() {
   super.onRestart()
   Log.d(TAG, "onRestart Called")
}
  1. DessertClicker를 다시 실행하여 Logcat을 확인하면 이번에는 onResume()의 로그가 찍혀있다.

onResume()

Activity가 처음부터 시작되면 3가지 생명주기 콜백 메서드가 순서대로 호출된다.

  • onCreate() : 앱을 생성
  • onStart() : Activity를 시작하고 화면에 표시
  • onResume() : Activity 포커스를 제공하고 사용자가 상호작용할 수 있도록 Activity를 준비한다.

Logcat에서 보이는 것처럼 onResume() 메서드는 다시 시장할 대상이 없어도 시작 시 호출된다.

  1. 디저트 그림을 몇 번 탭하고 뒤로 가기를 하면 Logcat에서 onPause(), onStop(), onDestroy()가 호출된다.

onPause(), onStop(), onDestroy()

onDestroy() 메서드의 실행은 Activity가 완전히 종료되었음을 의미한다. onDestroy()가 호출되면 시스템은 리소스가 삭제될 수 있음을 인식하고 메모리 정리를 한다.

Activity는 finish() 메서드를 사용하거나 사용자가 직접 강제 종료함으로써 완전히 종료될 수 있다. 아니면 오랫동안 화면에 표시되지 않으면 앱 자체적으로도 종료될 수 있다.

0개의 댓글