작업을 하면서 성능 및 메모리상 구조적으로 좋은쪽으로 짜려고 하다보니 궁금한게 많아져서 끄적끄적이고 있다.
우선 위의 3가지는 겉으로 보기에는 같은 기능을 가지고 있지만 세부적으로 보면 용도와 그 기능들이 차이가 있다!!
1. runOnUiThread(Runnable)
개요
- Activity에서 UI 관련 작업을 메인(UI) 스레드에서 실행하도록 강제할 때 사용합니다.
- 내부적으로 Handler를 사용하여 Looper.getMainLooper()를 통해 실행됩니다.
사용법
runOnUiThread(new Runnable() {
@Override
public void run() {
textView.setText("UI 업데이트");
}
});
특징
- Activity에서 직접 호출 가능 (this.runOnUiThread())
- UI 업데이트를 위해 간단한 코드라면 사용하기 편리함
- Activity가 종료되었을 때 호출하면 IllegalStateException이 발생할 가능성이 있음
동작: 현재 스레드가 UI 스레드가 아닐 경우, UI 스레드에서 작업을 즉시 실행. 현재 스레드가 이미 UI 스레드인 경우, 작업은 즉시 실행.
용도: UI 스레드에서 작업을 실행해야 하지만 현재 스레드가 UI 스레드가 아닌 경우에 사용
성능: 즉시 실행되므로 지연이 없음.
메모리: 메모리 사용량에 큰 영향을 미치지 않음. UI 스레드에서 직접 작업을 수행.
2. View.post(Runnable)
개요
- 특정 View가 UI 스레드에서 실행되도록 예약하는 방법
- View가 attach되어 있는 경우 실행됨
사용법
textView.post(new Runnable() {
@Override
public void run() {
textView.setText("UI 업데이트");
}
});
특징
- View가 생성된 후(UI 트리가 존재할 때) 실행됨
- View가 attach되지 않은 상태에서 실행하면 실행되지 않을 수 있음
- 특정 View에 연결된 UI 업데이트를 위해 적절함
동작: 지정된 View의 UI 스레드의 메시지 큐에 작업을 추가. View가 화면에 표시된 후 작업을 실행.
용도: View가 화면에 표시된 후에 작업을 실행할 필요가 있을 때 사용. 예를 들어, 레이아웃이 완전히 그려진 후에 작업을 실행해야 하는 경우 유용.
성능: 작업이 UI 스레드의 메시지 큐에 추가되므로, 즉시 실행되지 않고 약간의 지연이 있을 수 있음.
메모리: 지연된 작업이 메시지 큐에 저장되므로 메모리 사용량이 약간 증가할 수 있음.
3. Handler(Looper.getMainLooper()).post(Runnable)
개요
- Handler를 이용해 UI 스레드에서 실행되도록 예약하는 방법
- Handler는 메시지 큐를 사용하여 실행 예약을 조정할 수 있음
사용법
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
textView.setText("UI 업데이트");
}
});
특징
- runOnUiThread()와 유사하지만 Handler 객체를 직접 사용하여 관리 가능
- postDelayed()를 사용하여 일정 시간 이후 실행 가능
- removeCallbacks()를 통해 예약된 실행을 취소할 수도 있음
동작: Handler를 사용하여 메시지 큐에 작업을 추가합니다. Handler는 지정된 Looper와 연관된 스레드에서 작업을 실행.
용도: 특정 스레드에서 작업을 지연시키거나 큐에 작업을 추가할 때 사용. Handler를 사용하여 메인 스레드에서 작업을 지연시키려면 Looper.getMainLooper()를 사용.
성능: Handler를 사용하여 메시지 큐에 작업을 추가하므로, 작업이 실행되기까지 약간의 지연이 있을 수 있음.
메모리: Handler가 메시지 큐에 작업을 추가하기 때문에 메모리 사용량이 증가할 수 있으며, 특히 많은 작업을 큐에 추가할 때 메모리 관리에 주의.
주요 차이점
- 동작 시점:
- runOnUiThread: 현재 스레드가 UI 스레드가 아니면, UI 스레드에서 즉시 실행합니다.
- View.post: 지정된 View의 UI 스레드의 메시지 큐에 작업을 추가하여 View가 화면에 표시된 후 실행합니다.
- Handler: 지정된 Looper와 연관된 스레드에서 작업을 큐에 추가하고, 큐에서 작업을 실행합니다.
- 용도:
- runOnUiThread: UI 스레드에서 작업을 즉시 실행해야 할 때.
- View.post: View가 화면에 표시된 후 작업을 실행해야 할 때.
- Handler: 특정 스레드에서 작업을 지연시키거나 큐에 추가해야 할 때.
- 성능 및 메모리:
- runOnUiThread: 즉시 실행되므로 지연이 없음. 메모리 오버헤드가 거의 없음.
- View.post: 약간의 지연이 있을 수 있음. 메모리 오버헤드가 약간 있을 수 있음.
- Handler: 지연이 있을 수 있으며, 많은 작업을 큐에 추가할 경우 메모리 관리에 주의 필요.
결론
- 즉시 UI 스레드에서 작업을 실행해야 하는 경우: runOnUiThread를 사용하는 것이 적합.
- View의 상태에 따라 작업을 지연시키고 싶은 경우: View.post를 사용할 수 있음.
- 특정 스레드에서 작업을 지연시키거나 큐에 추가할 필요가 있는 경우: Handler를 사용하는 것이 적합.
■ 정리
- 간단한 UI 변경 → runOnUiThread()
- 특정 View에 대한 작업 → View.post()
- 예약 실행이 필요하거나 백그라운드 작업에서 UI 변경 → Handler.post()

그럼 Swift 에 대해서도 알아보도록 하자
1. DispatchQueue
Swift에서는 DispatchQueue를 사용하여 동시성을 관리하고, 다른 스레드에서 코드를 실행할 수 있습니다. 메인 스레드에서 코드를 실행하려면 다음과 같이 사용할 수 있습니다.
메인 큐
메인 스레드에서 코드를 실행하려면 다음 코드를 사용합니다:
DispatchQueue.main.async {
// UI 업데이트 코드를 여기에 작성합니다.
}
예시:
DispatchQueue.main.async {
self.myLabel.text = "업데이트된 텍스트"
}
2. performSelector(onMainThread:)
또 다른 방법으로 performSelector(onMainThread:with:waitUntilDone:)를 사용하여 메인 스레드에서 코드를 실행할 수 있습니다.
예시:
self.performSelector(onMainThread: #selector(updateUI), with: nil, waitUntilDone: false)
@objc func updateUI() {
// UI 업데이트 코드를 여기에 작성합니다.
myLabel.text = "업데이트된 텍스트"
}
3. Timer
일정 시간 간격으로 반복적으로 실행되는 코드를 원할 경우 Timer를 사용할 수 있습니다.
예시:
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
// 메인 스레드에서 실행되는 코드
self.myLabel.text = "1초마다 업데이트"
}
4. OperationQueue
작업을 관리할 때 OperationQueue를 사용할 수 있으며, 일부 작업이 메인 큐에서 실행되도록 지정할 수 있습니다.
예시:
let operationQueue = OperationQueue()
operationQueue.addOperation {
// 백그라운드 작업
let result = performLongRunningTask()
// 메인 스레드에서 UI 업데이트
DispatchQueue.main.async {
self.myLabel.text = result
}
}
요약
- DispatchQueue.main.async를 사용하여 메인 스레드에서 코드를 실행합니다.
- 구식 코드베이스에서는 performSelector(onMainThread:with:waitUntilDone:)를 사용할 수 있습니다.
- 반복 작업에는 Timer를 사용합니다.
- 복잡한 작업 종속성을 관리할 때는 OperationQueue를 사용합니다.
이러한 개념은 Android의 runOnUiThread, View.post, Handler와 유사하며, Swift에서도 UI 업데이트와 비동기 작업을 효과적으로 관리할 수 있도록 도와줍니다.
'개발 > Java' 카테고리의 다른 글
Java_ buildType 활용하여 debug, release 구분하기 (0) | 2024.10.02 |
---|---|
Java_ 지역변수 , 인스턴스 변수 차이 (0) | 2024.09.12 |
Java_ Rxjava blockingGet , subscribe ... (0) | 2024.08.25 |
Java_ Lazy Singleton (0) | 2024.08.25 |
AOS - Rxjava3 , Single , Disposable (0) | 2024.06.23 |