종종 간과하는 문제 해결 에피소드(feat. Handler, Thread)

2023. 4. 24. 00:30·Dev experience/Android
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
반응형
저작자표시 비영리 변경금지 (새창열림)

'Dev experience > 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
'Dev experience/Android' 카테고리의 다른 글
  • Codelab으로 LiveData 알아보기 - 5. Add a game-finished event(2)
  • Codelab으로 LiveData 알아보기 - 4. Add a game-finished event(1)
  • 구글 플레이 개발자 이름 주의 사항(오늘도 여전한 구글)
  • 원하는 화면에서 앱이 백그라운드로 진입 시 종료시키기(feat. Application)
BonusTrack02.dev
BonusTrack02.dev
공부, 일상
  • BonusTrack02.dev
    BonusTrack02.dev
    BonusTrack02.dev
  • 전체
    오늘
    어제
    • 분류 전체보기 (239)
      • Dev experience (86)
        • Android (85)
        • Kotlin (1)
      • Study (63)
        • Kotlin (27)
        • Swift (17)
        • Java (19)
      • 프로그래머스 (68)
      • 주저리주저리 (22)
        • 카페 (5)
        • 음식점 (4)
        • 컨퍼런스 (1)
        • 팝업스토어 (4)
        • 전시회 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Observer
    Material
    코루틴
    android
    room
    aac
    SWIFT
    코틀린
    오블완
    programmers
    daterangepicker
    PCCE
    jetpack
    자바
    배열
    viewModelScope
    스위프트
    CodeLab
    ViewModel
    티스토리챌린지
    getNumericValue
    안드로이드
    ios
    LiveData
    databinding
    MVVM
    프로그래머스
    coroutines
    Kotlin
    Java
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
BonusTrack02.dev
종종 간과하는 문제 해결 에피소드(feat. Handler, Thread)
상단으로

티스토리툴바