1. 시작하기 전에
이 Codelab에서는 Android 스튜디오에서 디버거를 사용하여 런타임 시 Dice Roller 앱에서 발생하는 작업을 검사하는 방법을 알아봅니다.
디버거는 Android 앱을 구동하는 코드 실행을 검사하여 버그를 수정할 수 있도록 하는 필수 도구입니다. 코드 실행을 정지하고 코드의 변수와 메서드, 기타 측면과 수동으로 상호작용할 지점을 지정할 수 있습니다.
기본 요건
- Android 스튜디오에 관한 기본 지식
- Android 스튜디오에서 기본 Jetpack Compose 앱을 만들고 실행하는 능력
- 대화형 Dice Roller 앱 만들기 Codelab 완료
학습 내용
- Android 앱에 디버거를 연결하는 방법
- 디버거가 연결된 앱을 실행하는 방법
- 디버거의 기본적인 기능을 사용하는 방법
- 디버거의 일반적인 용도
필요한 항목
- Android 스튜디오가 설치된 컴퓨터
- Compose의 Dice Roller 앱 솔루션 코드
2. 코드 따라 하기 동영상 시청(선택사항)
교육 과정 강사가 Codelab을 완료하는 모습을 보려면 아래 동영상을 재생하세요.
동영상을 전체 화면으로 펼쳐(동영상 하단의 오른쪽 모서리에 있는 아이콘 사용) Android 스튜디오와 코드를 더 선명하게 보는 것이 좋습니다.
이 단계는 선택사항입니다. 이 동영상을 건너뛰고 Codelab 안내를 바로 시작할 수도 있습니다.
3. 시작 코드 가져오기
시작하려면 코드를 다운로드합니다.
또는 코드에 관한 GitHub 저장소를 클론해도 됩니다.
$ git clone https://github.com/google-developer-training/basic-android-kotlin-compose-training-dice-roller.git $ cd basic-android-kotlin-compose-training-dice-roller
GitHub 저장소에서 코드를 찾아볼 수 있습니다.
4. 디버거 실행
디버거를 앱과 함께 실행하는 방법에는 두 가지가 있습니다.
- 디버거를 기기나 에뮬레이터에서 실행되는 기존 앱 프로세스에 연결합니다.
- 디버거로 앱을 실행합니다.
두 방법 모두 어느 정도 동일한 작업을 실행합니다. 두 가지 방법을 모두 숙지한 후 원하는 방법을 선택하거나 필요한 방법을 선택하면 됩니다.
앱 프로세스에 디버거 연결
앱이 이미 실행 중인 경우 디버거를 앱에 연결할 수 있습니다.
앱 프로세스에 디버거를 연결하려면 다음 단계를 따르세요.
- Attach Debugger to Android Process(Android 프로세스에 디버거 연결)를 클릭합니다.
Choose Process(프로세스 선택) 대화상자가 열리면 디버거를 연결할 프로세스를 선택하면 됩니다.
com.example.diceroller
를 선택하고 OK(확인)를 클릭합니다.
Android 스튜디오 하단에 디버거가 대상 기기 또는 에뮬레이터에 연결되었다고 나타내는 메시지와 함께 Debug(디버그) 창이 표시됩니다.
디버거를 앱에 연결했습니다. 이것이 의미하는 바와 디버거로 수행할 수 있는 작업에 대해서는 이 Codelab의 후반부에서 알아봅니다. 이제 디버거가 이미 연결되어 있는 앱을 실행하는 방법을 알아봅니다.
디버거로 앱 실행
처음부터 디버거를 사용하려는 경우 디버거를 사용하여 앱을 실행하면 시간을 절약할 수 있습니다. 또한 앱이 실행될 때만 실행되는 코드를 디버그하려면 이미 디버거가 연결된 앱을 실행해야 합니다.
디버거로 앱을 실행하려면 다음 단계를 따르세요.
- Debug(디버그) 창에서 Stop(중지)을 클릭한 후 기기나 에뮬레이터에서 앱을 닫습니다.
- Debug 'app'을 클릭합니다.
Android 스튜디오 하단에 일부 콘솔 출력과 함께 동일한 Debug(디버그) 창이 표시됩니다.
이제 디버거 실행 방법을 익혔습니다. 이제 사용 방법을 알아봅니다.
5. 디버거 사용
Debug 창
Debug 창 상단에 여러 버튼이 있지만 이러한 버튼은 지금은 별 의미가 없으며 대부분 비활성화되어 있고 클릭할 수 없습니다. 이 섹션에서는 더 일반적으로 사용되는 디버거의 기능을 다룹니다. 이 Codelab에서는 관련성이 있는 경우 이러한 버튼에 대해 설명합니다.
디버거를 처음 실행하면 Debug 창에 여러 버튼이 표시됩니다. Debug(디버그) 창 상단에는 Debugger(디버거) 버튼과 Console(콘솔) 버튼이 표시됩니다.
Console(콘솔) 버튼은 앱의 logcat 출력을 표시합니다. 코드에 로그 구문이 있으면 이 코드가 실행될 때 출력이 표시됩니다.
Debugger(디버거) 버튼은 별도의 창 3개를 표시하는데 지금은 비어 있습니다. 디버거를 사용하고 있지 않기 때문입니다.
- 프레임 표시
- 평가 및 watch 표현식 항목
- Variables(변수) 창
일반적인 디버거 기능 사용
중단점 설정
디버거의 주요 기능 중 하나는 중단점을 사용하여 특정 코드 줄에서 실행을 중지할 수 있다는 것입니다.
Android 스튜디오에서 중단점을 설정하려면 특정 코드 줄로 이동하여 줄 번호 옆의 여백을 클릭해야 합니다. 중단점을 설정 해제하려면 여백에 있는 기존 중단점을 클릭하면 사라집니다.
- 직접 시도해 보려면
imageResource
변수가 설정된 중단점을 설정합니다.
Resume Program 버튼 사용
마지막 섹션에서는 imageResource
변수가 설정된 중단점을 설정합니다. 이 중단점은 이 명령에서 실행이 정지되도록 합니다. 디버거로 코드 실행이 정지된 경우 앱을 계속 실행하려면 실행을 계속해야 할 수 있습니다. 가장 쉬운 방법은 Resume Program 버튼을 사용하는 것입니다.
프로그램을 재개하려면 다음 단계를 따르세요.
- Debug 'app'을 클릭합니다. 앱이 실행된 후 다음과 같은 이미지가 표시됩니다.
프로그램을 재개하기 전에 디버거가 실행을 정지할 때 화면에 표시되는 내용을 설명하는 것이 중요합니다.
- 이제 Debug 창의 버튼을 대부분 클릭할 수 있습니다.
- Frames 창에는 많은 정보가 표시됩니다. 여기에는 중단점이 설정된 줄 참조가 강조표시된 상태로 포함되어 있습니다.
- Variables 창에는 여러 항목이 표시되지만, 이 앱에는 변수가 많지 않으므로 현재 이 Codelab 범위와 관련된 정보는 많지 않습니다. 하지만 변수 검사 기능은 디버거의 필수 기능입니다. 런타임 시 코드에서 어떤 상황이 발생하는지에 관한 유용한 정보를 제공하기 때문입니다. 이 Codelab 후반부에서는 변수를 검사하는 방법을 자세히 설명합니다.
기기나 에뮬레이터에서 앱을 살펴보면 앱이 코드 줄에서 정지되어 빈 화면이 표시됩니다. 구체적으로는 중단점에서 실행이 중지되었고 UI가 아직 렌더링되지 않았습니다.
중단점이 설정되었다고 해서 앱이 항상 즉시 중단되지는 않는다는 점에 유의하세요. 코드에서 중단점을 배치하는 위치에 따라 다릅니다. 여기서는 앱이 시작될 때 실행되는 줄에 배치했습니다.
핵심은 중단점이 설정된 줄을 실행하려고 할 때만 앱이 중단점에서 정지된다는 점입니다. 디버거를 진행하는 방법에는 여러 가지가 있지만 지금은 Resume Program(프로그램 재개) 버튼을 사용합니다.
- Resume Program(프로그램 재개)을 클릭합니다.
이제 다음과 같은 이미지가 표시됩니다.
대부분의 정보가 사라지고 버튼은 다시 클릭할 수 없게 됩니다. 앱은 기기나 에뮬레이터에 정상적으로 표시됩니다. 코드가 더 이상 중단점에서 정지되지 않고 앱이 정상 실행 상태이기 때문입니다. 디버거가 연결되어 있지만 중단점이 설정된 코드 줄을 실행하려는 시도가 있을 때까지는 별다른 작업을 하지 않습니다. 이 중단점은 다음 예시에서 유용하므로 그대로 둡니다.
Step Into 버튼 사용
디버거의 Step Into 버튼을 사용하면 런타임 시 간단하게 코드를 자세히 살펴볼 수 있습니다. 명령이 메서드 또는 다른 코드를 호출하는 경우 Step Into 버튼을 사용하면 디버거를 실행하여 중단점을 설정하기 전에 수동으로 탐색할 필요 없이 코드를 입력할 수 있습니다.
Step Into 버튼을 사용하려면 다음 단계를 따르세요.
DiceRollerApp()
함수가 호출되는MainActivity
클래스의onCreate()
함수에서setContent
람다 본문에 중단점을 만듭니다.
- Debug 'app'을 클릭하여 디버거로 앱을 다시 실행합니다.
DiceRollerApp()
함수가 호출되는 줄에서 실행이 정지됩니다. - Step Into를 클릭합니다.
이제 40번 줄이 강조표시되고 Debug(디버그) 창의 Frames(프레임) 창에는 코드가 40번 줄에서 정지되었다고 표시됩니다.
Frames(프레임) 창을 펼치면 강조표시된 줄 뒤에 있는 줄이 invoke:
로 시작하고 그 뒤에 줄 번호(이전 이미지에서는 32)가 오는 것을 확인할 수 있습니다. 이를 호출 스택이라고 합니다. 기본적으로 코드 실행을 현재 줄로 이끄는 호출 체인을 보여줍니다. 여기서는 32번 줄이 DiceRollerApp()
함수를 호출하는 명령을 보유합니다.
디버거가 이 함수 호출에 설정된 중단점에서 멈췄을 때 Step Into 버튼을 클릭하면 디버거가 해당 함수로 들어가 함수가 선언된 40번 줄로 실행을 이끕니다. 강조표시된 줄은 실행이 정지된 위치를 나타냅니다. 강조표시된 줄 뒤의 줄에 연결된 줄 번호가 있는 경우 이는 실행 경로를 나타냅니다. 이 경우 디버거는 32번 줄의 명령이 40번 줄로 안내했음을 나타냅니다.
- Resume Program(프로그램 재개)을 클릭합니다.
이렇게 하면 원래 설정한 중단점으로 이동합니다. 첫 번째 예시에서 실행을 중지했을 때 표시된 내용을 좀 더 이해할 수 있습니다. 다음은 Resume program(프로그램 재개) 섹션의 여섯 번째 단계와 동일한 사진입니다.
호출 스택에서 보면 DiceWithButtonAndImage()
함수가 50번 줄에서 정지했고 이 함수는 32번 줄에서 호출된 DiceRollerApp()
함수의 41번 줄에서 호출된 것을 확인할 수 있습니다. 호출 스택 기능을 통해 실행 경로를 파악할 수 있습니다. 이는 함수가 앱의 여러 위치에서 호출될 때 매우 유용합니다.
Step Into 버튼을 사용하면 함수를 입력하고 함수 자체에서 중단점을 설정하지 않고도 실행을 정지할 수 있습니다. 여기서는 DiceRollerApp()
함수 호출에서 중단점을 설정합니다. Step Into 버튼을 클릭하면 실행이 DiceRollerApp()
함수에서 정지됩니다.
Dice Roller는 파일이나 클래스, 함수가 많지 않으므로 상당히 작은 앱입니다. 큰 앱으로 작업하는 경우 디버거의 Step Into 기능은 더 유용해집니다. 코드를 직접 탐색할 필요 없이 코드를 상세히 살펴볼 수 있기 때문입니다.
Step Over 버튼 사용
Step Over 버튼을 사용하면 런타임에 앱 코드를 단계별로 실행할 수 있습니다. 이 버튼을 통해 실행을 다음 코드 줄로 이동하고 디버거를 진행합니다.
Step Over 버튼을 사용하려면 다음 단계를 따르세요.
- Step Over를 클릭합니다.
디버거가 다음 실행 줄인 51번 줄에서 코드를 정지한 것을 확인할 수 있습니다. 각 줄을 연속적으로 단계별로 실행할 수 있습니다.
Step Out 버튼 사용
Step Out 버튼은 Step Into 버튼과는 반대로 작동합니다. 호출 스택을 드릴다운하는 대신 Step Out 버튼은 호출 스택으로 이동합니다.
Step Out 버튼을 사용하려면 다음 단계를 따르세요.
- Step Out을 클릭합니다.
프로그램이 정지된 줄을 알 수 있나요?
- 디버거가
DiceRollerApp()
함수에서 나와 이 함수를 호출한 줄로 돌아왔습니다.
Step Out 버튼은 메서드 호출 스택에 너무 깊이 들어간 경우 유용한 도구입니다. 들어간 각 메서드의 모든 코드를 단계별로 실행하지 않고도 호출 스택 위로 이동할 수 있습니다.
변수 검사
이 Codelab 앞부분에서는 Variables 창에 관해 간략하게 설명했습니다. 이를 통해 창에 표시된 변수를 검사하여 앱 문제를 디버그하는 방법을 자세히 설명했습니다.
변수를 검사하려면 다음 단계를 따르세요.
- 중단점을 클릭하여
DiceRollerApp()
함수가 호출되는 위치에서 중단점을 삭제하고imageResource
변수가 설정된 중단점은 그대로 둡니다. - Debug 'app'을 클릭합니다.
result$delegate
변수가 값이 1인MutableState
인 것을 확인할 수 있습니다. 정의된 변수는 값이 1인mutableStateOf
로 인스턴스화되기 때문입니다.MutableState
는 결과 변수가 변경될 수 있는 상태를 보유하고 있음을 의미합니다.
- Resume Program(프로그램 재개)을 클릭합니다.
- 앱에서 Roll을 클릭합니다. 코드가 중단점에서 다시 정지되며
result$delegate
변수의 값이 다르게 표시될 수 있습니다.
이 이미지에서 result$delegate
변수의 변경 가능한 상태는 값 2를 보유합니다. 이는 런타임 시 디버거를 사용하여 변수를 검사하는 방법을 보여줍니다. 더 많은 기능을 갖춘 앱에서는 변수의 값으로 인해 비정상 종료가 발생할 수 있습니다. 디버거를 사용하여 변수를 검사하면 비정상 종료에 관한 유용한 정보를 더 많이 얻을 수 있어 버그를 수정할 수 있습니다.
6. 결론
축하합니다. Android 스튜디오에서 디버거를 사용했습니다.
요약
- 디버거를 앱에 연결합니다.
- 디버거가 이미 연결된 앱을 실행합니다.
- 디버거 창을 알아봅니다.
- 중단점을 설정합니다.
- 디버거에서 프로그램을 재개합니다.
- Step Into 버튼을 사용합니다.
- Step Over 버튼을 사용합니다.
- Step Out 버튼을 사용합니다.
- 디버거를 사용하여 변수를 검사합니다.