지난번 질문에 이어 이번엔 안드로이드 개발을 시켜보았습니다. 이전 질문은 1편 2편 여기로 가시면 됩니다.
ChatGPT로 안드로이드 개발이 될까 싶어 다음과 같은 질문을 했습니다.
이전에 코틀린으로 개발한 것이 있어 비교해보려 같은 기능을 요청해보았습니다.
질문) 안드로이드로 스톱워치를 만드는 코드를 작성해줄 수 있어? 언어는 코틀린으로 해줘
될까 싶었지만 바로 된다고 하는 ChatGPT 였습니다.
class MainActivity : AppCompatActivity() {
private var isRunning = false
private var elapsedTime: Long = 0
private lateinit var handler: Handler
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
handler = Handler(Looper.getMainLooper())
}
private val runnable: Runnable = object : Runnable {
override fun run() {
val hours = (elapsedTime / 3600000).toInt()
val minutes = ((elapsedTime - hours * 3600000) / 60000).toInt()
val seconds = ((elapsedTime - hours * 3600000 - minutes * 60000) / 1000).toInt()
val millis = (elapsedTime - hours * 3600000 - minutes * 60000 - seconds * 1000).toInt()
val time = String.format("%d:%02d:%02d.%03d", hours, minutes, seconds, millis)
findViewById<TextView>(R.id.time_view).text = time
if (isRunning) {
elapsedTime += 10
handler.postDelayed(this, 10)
}
}
}
fun startTimer(view: View) {
isRunning = true
handler.post(runnable)
}
fun stopTimer(view: View) {
isRunning = false
handler.removeCallbacks(runnable)
elapsedTime = 0
findViewById<TextView>(R.id.time_view).text = "0:00:00.000"
}
}
이 코드는 액티비티 클래스 안에 타이머를 시작하고 멈추는 두 개의 메소드 startTimer와 stopTimer를 구현합니다. 타이머를 시작하면 isRunning 변수를 true로 설정하고, handler.post(runnable)을 호출하여 runnable 객체의 run() 메소드를 실행합니다. run() 메소드에서는 경과 시간을 계산하고 텍스트 뷰에 표시합니다. 타이머를 멈추면 isRunning 변수를 false로 설정하고, handler.removeCallbacks(runnable)을 호출하여 runnable 객체의 실행을 중지하고, 경과 시간을 초기화합니다.
이 코드에서는 Handler와 Runnable을 사용하여 타이머를 구현했습니다. Handler 클래스는 메인 스레드에서 실행되는 Runnable 객체를 관리하고, post() 메소드를 사용하여 지정된 Runnable 객체를 실행할 수 있습니다. postDelayed() 메소드를 사용하면 지정된 시간 이후에 Runnable 객체를 실행할 수도 있습니다.
위의 코드는 ChatGPT가 실제로 작성한 코드이며 코드 아래 설명도 ChatGPT가 직접 설명해주는 것입니다.
ChatGPT가 작성하면서 코드가 쭉 나오는데 직접 보니 와.. 대단하다라는 생각이 들었습니다.
그런데 작성한 것은 MainActivity.kt의 코드 뿐이였습니다. xml도 필요하고 gradle 등등의 코드도 알려줄 수 있을까 싶어 추가로 질문을 하였습니다.
질문) 저 코드가 다 나타낸거야? xml이나 Androidmanifest나 gradle 코드도 알려줘
제가 작성해 드린 코드는 스톱워치의 핵심 로직인데요, 실제 앱을 만들기 위해서는 XML 레이아웃 파일과 AndroidManifest.xml 파일도 작성해야 합니다.
XML 레이아웃 파일에서는 UI 구성을 담당하고, AndroidManifest.xml 파일에서는 앱 정보와 권한 등을 설정합니다. 또한, Gradle 파일에서는 앱이 사용할 라이브러리를 설정합니다.
하지만, XML 레이아웃 파일과 AndroidManifest.xml 파일, Gradle 파일 등은 내용이 복잡하고 매우 다양하기 때문에 여기서 모두 다루기는 어렵습니다. 대신, 안드로이드 공식 문서와 다양한 개발자 커뮤니티에서 제공하는 자료들을 참고하시면 도움이 될 것입니다.
이처럼 개인적으로 찾아서 작성해야한다는 느낌이였습니다. 하지만 질문을 바꿔서 물어본다면 어떻게 될까 싶어 또 질문을 진행하였습니다.
질문) 그러면 가장 기본적인 코드로 알려줘
가장 기본적인 코드로 스톱워치를 만드는 예제를 알려드리겠습니다.
우선, activity_main.xml 파일을 열어서 다음과 같이 레이아웃을 작성해주세요.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/stopwatch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="60sp"
android:text="00:00:00"
android:layout_centerInParent="true"/>
<Button
android:id="@+id/start_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Start"
android:layout_alignParentStart="true"
android:layout_marginStart="50dp"
android:layout_alignParentBottom="true"
android:onClick="startTimer"/>
<Button
android:id="@+id/stop_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stop"
android:layout_alignParentEnd="true"
android:layout_marginEnd="50dp"
android:layout_alignParentBottom="true"
android:onClick="stopTimer"/>
</RelativeLayout>
그리고 MainActivity.kt 파일을 열어서 다음과 같이 코드를 작성해주세요.
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import android.os.SystemClock
import android.widget.TextView
class MainActivity : AppCompatActivity() {
private lateinit var stopwatch: TextView
private lateinit var startButton: Button
private lateinit var stopButton: Button
private var running: Boolean = false
private var timeElapsed: Long = 0L
private val handler: Handler = Handler()
private val runnable: Runnable = object : Runnable {
override fun run() {
val currentTime = SystemClock.uptimeMillis()
timeElapsed += currentTime - lastTime
lastTime = currentTime
val time = timeElapsed.toInt()
val seconds = time / 1000
val minutes = seconds / 60
val hours = minutes / 60
val secondsDisplay = seconds % 60
val minutesDisplay = minutes % 60
val hoursDisplay = hours % 24
stopwatch.text = String.format("%02d:%02d:%02d", hoursDisplay, minutesDisplay, secondsDisplay)
handler.postDelayed(this, 1000)
}
}
private var lastTime: Long = 0L
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
stopwatch = findViewById(R.id.stopwatch)
startButton = findViewById(R.id.start_button)
stopButton = findViewById(R.id.stop_button)
startButton.setOnClickListener {
startTimer()
}
stopButton.setOnClickListener {
stopTimer()
}
}
fun startTimer() {
if (!running) {
running = true
lastTime = SystemClock.uptimeMillis()
handler.postDelayed(runnable, 0)
}
}
fun stopTimer() {
if (running) {
running = false
handler.removeCallbacks(runnable)
timeElapsed = 0L
lastTime = 0L
stopwatch.text
전체 코드가 작성되기를 기다렸으나 위의 코드 상태에서 멈춰버렸습니다. 그래서 이어서 작성해달라고 질문을 다시하였습니다.
질문) 코드가 끊긴거 같은데 이어서 작성해줘
class MainActivity : AppCompatActivity() {
private lateinit var stopwatchTextView: TextView
private lateinit var startButton: Button
private lateinit var pauseButton: Button
private lateinit var resetButton: Button
private var timeInMillis: Long = 0L
private var isStopwatchRunning = false
private lateinit var timer: CountDownTimer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
stopwatchTextView = findViewById(R.id.stopwatchTextView)
startButton = findViewById(R.id.startButton)
pauseButton = findViewById(R.id.pauseButton)
resetButton = findViewById(R.id.resetButton)
startButton.setOnClickListener {
startStopwatch()
}
pauseButton.setOnClickListener {
pauseStopwatch()
}
resetButton.setOnClickListener {
resetStopwatch()
}
}
private fun startStopwatch() {
timer = object : CountDownTimer(Long.MAX_VALUE, 10L) {
override fun onTick(millisUntilFinished: Long) {
timeInMillis += 10L
val minutes = TimeUnit.MILLISECONDS.toMinutes(timeInMillis)
val seconds = TimeUnit.MILLISECONDS.toSeconds(timeInMillis) -
TimeUnit.MINUTES.toSeconds(minutes)
val milliseconds = timeInMillis - TimeUnit.SECONDS.toMillis(seconds) -
TimeUnit.MINUTES.toMillis(minutes * 60)
stopwatchTextView.text = "${String.format("%02d", minutes)}:" +
"${String.format("%02d", seconds)}:" +
"${String.format("%03d", milliseconds)}"
}
override fun onFinish() {}
}
timer.start()
isStopwatchRunning = true
}
private fun pauseStopwatch() {
timer.cancel()
isStopwatchRunning = false
}
private fun resetStopwatch() {
timeInMillis = 0L
stopwatchTextView.text = "00:00:000"
isStopwatchRunning = false
}
}
위 코드는 안드로이드 스튜디오에서 새로운 앱 프로젝트를 만들고, 액티비티를 추가한 후에 작성된 가장 기본적인 코드입니다. 앱 실행 시 화면에는 스톱워치의 시간을 나타내는 TextView와 시작, 일시정지, 리셋 버튼이 나타납니다. 사용자는 시작 버튼을 누르면 스톱워치가 시작되고, 일시정지 버튼을 누르면 스톱워치가 일시정지되며, 리셋 버튼을 누르면 스톱워치가 초기화됩니다.
이어서 작성해달라는 질문에 끊긴 코드에 이어지는게 아닌 새로운 MainActivity.kt 파일을 작성하였습니다. 질문할때 마다 다양한 방식의 코드가 나오길래 출처가 궁금해졌었습니다.
질문) 위의 코드를 작성할때 참고한 자료가 있어?
제가 작성한 코드는 안드로이드에서 기본적으로 제공하는 시스템 함수와 API를 활용한 코드이며, 따로 참고한 자료는 없습니다.
하지만 이와 관련하여 참고할 수 있는 자료들은 다음과 같습니다.
안드로이드 공식 문서: https://developer.android.com/docs/
안드로이드 개발자 가이드: https://developer.android.com/guide/
안드로이드 개발자 블로그: https://android-developers.googleblog.com/
온라인 개발 커뮤니티: Stack Overflow, GitHub 등
여기서 더 나아가 결과물을 링크로해서 따로 보여줄 수 있을까 싶어 추가 질문을하였습니다.
질문) 위의 앱을 실행하고 나서 화면이나 데모 영상이 있을까?
제가 작성한 코드는 앱의 레이아웃만 구성한 것이기 때문에 실행해도 화면에는 아무것도 나타나지 않습니다. 만약 화면이나 데모 영상이 필요하시다면 코드에 추가적인 기능을 구현하시거나, 기존에 작성된 스톱워치 앱을 검색해서 참고하시는 것이 좋습니다.
아쉽게도 방법은 없었나 봅니다.
그러하여 위에서 작성한 코드를 직접 안드로이드 스튜디오에 적용해보았습니다.
그 결과 제가 질문을 잘못해버려서 아래와 같이 오류가 발생하였습니다.
위의 사진은 MainActivity.kt의 코드 중 일부입니다. MainActivity.kt 파일과 activity_main.xml을 따로 따로 받아버려서 id 및 버튼이 누락되는 현상이 발생했습니다. 그래도 저정도는 버튼 추가하고 이름만 바꿔주면 되니까 직접 수정을하였습니다.
그렇게 에러를 없애고 실행한 결과..
놀랍게도 잘 작동하였습니다.
물론 아래 버튼의 레이아웃은 제가 하나를 임의로 추가해서 정리가 안되어 있습니다.
추가하기 전에는 버튼이 2개가 있었는데 위치도 다 맞춰져 있었습니다.
후기)
ChatGPT에게 코드를 짜도록 시키기 위해서는 어느정도의 지식을 갖고 있어야 코드가 쓸모 있는지 원하는건지 파악할 수 있을 듯 했습니다.
만약 정말 1도 개발에 대한 지식이 모른채 질문을하고 코드를 얻는 경우
위의 질문에도 있듯이 코드가 짤린 것도 모를 수도 있습니다.
그래도 코드 분석 따로 안하고 에러 조금 고치고 돌리면 잘 돌아갈 정도로 구실을 한다는 점이 정말 신기했습니다.
아마 제가 질문을 제대로 안해서 그럴 수도 있고 질문의 질에 따라 코드의 방식도 바뀌는 듯 합니다.
이후에도 시간이 된다면 ChatGPT로 다양한 기능과 코드 수정하는 것을 올려보도록 하겠습니다.
ChatGPT로 짠 코드 확인하려면 여기를 클릭하세요.
'ChatGPT' 카테고리의 다른 글
요즘 유행인 ChatGPT에게 여러가지 질문을 해보았다. 2편 (0) | 2023.02.14 |
---|---|
요즘 유행인 ChatGPT에게 여러가지 질문을 해보았다. 1편 (0) | 2023.02.14 |