728x90
반응형
오늘은 회사에서 마주한 에러를 해결했던 에피소드를 적어보고자 한다.
사실, 되게 사소하지만 크리티컬한 문제였다.
가장 먼저 오늘 마주한 에러를 다시 재현하기 위해 내 노트북에서 샘플앱을 만들었다 ㅋㅋㅋㅋㅋ
마주한 에러 로그를 첨부하겠다.
java.lang.RuntimeException: Can't create handler inside thread Thread[Timer-0,5,main] that has not called Looper.prepare()
at android.os.Handler.<init>(Handler.java:227)
at android.os.Handler.<init>(Handler.java:129)
at android.app.Dialog.<init>(Dialog.java:138)
at android.app.Dialog.<init>(Dialog.java:190)
at androidx.activity.ComponentDialog.<init>(ComponentDialog.kt:38)
at androidx.appcompat.app.AppCompatDialog.<init>(AppCompatDialog.java:55)
at androidx.appcompat.app.AlertDialog.<init>(AlertDialog.java:98)
at androidx.appcompat.app.AlertDialog$Builder.create(AlertDialog.java:983)
at com.bonustrack02.sampletimer.MainActivity$onCreate$timerTask$1.run(MainActivity.kt:23)
at java.util.TimerThread.mainLoop(Timer.java:563)
at java.util.TimerThread.run(Timer.java:513)
생각보다 심플한 에러이고, 단박에 알아볼 사람도 많을 에러이다.
다른 스레드에서 UI 작업을 했다.
나의 경우는 Timer 안에서 AlertDialog를 create했다.
특히, 이런 다이얼로그를 보여주는 함수를 만들어 사용해서 더욱 눈에 띄지 않았고 그래서 이런 에러를 마주하게 되었다고 생각한다.
이럴 때는 매우 간단하게 AlertDialog를 create하고 show하는 코드를 runOnUiThread 함수로 감싸버리면 된다.
수정 전
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val timer = Timer()
val timerTask = object : TimerTask() {
override fun run() {
AlertDialog
.Builder(this@MainActivity)
.setMessage("Hi")
.setPositiveButton("Ok", null)
.create()
.show()
}
}
timer.schedule(timerTask, 1000)
}
수정 후
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(binding.root)
val timer = Timer()
val timerTask = object : TimerTask() {
override fun run() {
runOnUiThread {
AlertDialog
.Builder(this@MainActivity)
.setMessage("Hi")
.setPositiveButton("Ok", null)
.create()
.show()
}
}
}
timer.schedule(timerTask, 1000)
}
나는 회사에서 아직 자바를 사용 중이라 runOnUiThread 메소드를 쓰면 코드가 조금 지저분해지긴 하지만
코틀린에서는 덜 지저분해지기 때문에 크게 부담이 없는 듯하다.
아무튼 UI 작업을 메소드로 만들어 사용할 때 해당 함수가 메인 스레드가 아닌 곳에서 호출되는지 검사할 필요가 있다.
728x90
반응형
'Android' 카테고리의 다른 글
Codelab으로 LiveData 알아보기 - 5. Add a game-finished event(2) (0) | 2023.04.27 |
---|---|
Codelab으로 LiveData 알아보기 - 4. Add a game-finished event(1) (0) | 2023.04.25 |
구글 플레이 개발자 이름 주의 사항(오늘도 여전한 구글) (0) | 2023.03.27 |
원하는 화면에서 앱이 백그라운드로 진입 시 종료시키기(feat. Application) (0) | 2023.03.25 |
Android Studio Waiting For Debugger 현상 해결 (0) | 2023.03.07 |