Android runOnUiThread

HEETAE HEO·2022년 6월 29일
0
post-thumbnail

Android OS는 UI 자원에 Main Thread와 Sub Thread가 동시 접근하여 동기화 이슈를 발생시키는 것을 방지시키기 위해 UI자원 사용은 UI Thread에서만 가능하도록 만들었습니다. Android에서 제공하는 Message나 Runnable 객체를 UI 스레드 쪽에서 동작시킬 수 있는 방법이 4가지 있습니다.

1. Activity.runOnUiThread()

  1. Handler.post()

  2. View.post()

  3. AsyncTask 클래스

오늘은 runOnUiThread()에 대해서 설명하고 공부하는 글을 작성해보려고 합니다.

runOnUiThread

Android Developer에서는 다음과 같이 설명합니다.

  • UI 스레드에서 지정된 작업을 실행합니다. 현재 스레드가 UI 스레드이면 작업이 즉시 실행됩니다. 현재 스레드가 UI 스레드가 아닌 경우 조치는 UI 스레드의 이벤트 큐에 게시됩니다.

지금 작업을 수행하는 스레드가 메인 스레드라면 즉시 작업을 시작하고 메인 스레드가 아니라면 스레드 이벤트 큐에 쌓아두는 기능을 하는게 runOnUiThread입니다.

runOnUiThread는 액티비티 클래스에서 제공되는 메서드입니다. 개발자 만든 Runnable 객체를 메인 스레드에서 실행되게 하는 메서드입니다. 현재 메서드가 메인 스레드인지 여부를 검사해 메인 스레드가 아니라면 post()를 실행하고 맞다면 Runnable의 run()을 실행합니다.

runOnUiThread의 구조

public final void runOnUiThread(Runnable action) {
	if(Thread.currentThread() != mUiThread) {
    	mHandler.post(action);
    } else {
    	action.run();
    }
}

Thread.currentThread()로 현재 스레드가 메인 스레드인지 확인하고 맞으면 바로 action을 run()하며 아니라면 해들러의 post()로 Runnable 객체를 넘깁니다. 이 때 넘겨진 Runnable 객체는 이벤트 큐에 쌓여서 번호표를 뽀고 자기 순서가 올 때까지 기다리면 됩니다.

runOnUiThread 예시

WorkThread에서 작업을 수행하려고 할 떄

calss MainActivity : AppCompatActivity() { 


	private lateinit var binding : ActivityMainBinding
	
	override fun onCreate(savedInstanceState : Bundle?){
    	super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        binding.change_btn.setOnClickListener {
        	thread { 
            binding.changeText.text = "변경"
        }.start()
    }
}

위와 같이 구현을 하게 된다면 바로 error가 발생합니다.
사용자 이벤트의 경우 UIThread에서(Main) 동작을 해야하는데 SubThread에서 수행을 하였기 때문입니다.

calss MainActivity : AppCompatActivity() { 


	private lateinit var binding : ActivityMainBinding
	
	override fun onCreate(savedInstanceState : Bundle?){
    	super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)
        
        binding.change_btn.setOnClickListener {
        	runOnUiThread { 
            binding.changeText.text = "변경"
        }
    }
}

다음과 같이 runOnUiThread를 사용해서 UiThread인지 확인한 후 action을 수행하게 됩니다.

profile
Android 개발 잘하고 싶어요!!!

0개의 댓글