일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- kotlin
- CustomView
- lifecycle
- Algorithm
- room
- activity
- 코틀린
- CollapsingToolbarLayout
- notification
- hilt
- 알림
- 알고리즘
- sqlite
- ViewModel
- 안드로이드
- AppBarLayout
- HTTP
- CoordinatorLayout
- 백준
- View
- onLayout
- BOJ
- DataBinding
- Behavior
- LiveData
- Coroutine
- recyclerview
- onMeasure
- Navigation
- Android
- Today
- Total
개발일지
Android in A..Z - Handler 본문
안드로이드는 기본적으로 싱글 쓰레드이다. 그렇기 때문에 메인 쓰레드에서 처리 시간이 긴 명령(데이터 베이스, 네트워크 등)을 작성하면 버벅거린다. 따라서 처리 시간이 긴 명령은 서브 쓰레드를 만들어서 처리하는게 이상적이다. 하지만 멀티 쓰레드 환경에서 나오는 여러가지 이슈 때문에 안드로이드는 UI를 메인 쓰레드에서 밖에 바꾸지 못한다. 따라서 서브 쓰레드에서 UI를 변경하려면 Handler 객체를 이용하여 메인 쓰레드와 통신해야 한다. 핸들러는 메시지뿐만 아니라 Runnable을 전달할 수 있다.
Handler
핸들러는 루퍼에 의존적입니다. 핸들러를 생성하면 루퍼를 연결해야 합니다. 핸들러를 생성할 때 생성자로 루퍼를 전달하여 다른 쓰레드의 루퍼를 연결할 수 있고, 아무것도 전달하지 않으면 핸들러를 생성한 쓰레드의 루퍼를 연결합니다.
현재 후자의 방법은 Deprecated 상태입니다.
핸들러를 통해 post를 통해 Runnable를 전달하거나 sendMessage를 통해 Message를 다른 Looper로 전달할 수 있으며, handleMessage를 통해 다른 Looper에서 전달받은 Message를 처리할 수 있습니다.
(Handler를 상속받고 handleMessage를 구현할 수 있습니다.
Looper
루퍼는 쓰레드에 하나씩 존재합니다(새로 생긴 thread는 Looper.prepare()로 생성하고 연결하면 된다). Looper는 MessageQueue를 가지고 있으며, 다른 Handler로 받은 Runnable과 Message를 MessageQueue에 저장합니다. Looper는 적절한 때에 적절한 Handler에게 Message를 전달합니다.
예시
Runnable 전달
post.setOnClickListener {
Handler(Looper.getMainLooper()).post {
text.text = "Post"
}
}
Message 전달
message.setOnClickListener {
object: Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if(msg.what == 1000) {
text.text = "Message"
}
}
}.sendEmptyMessage(1000)
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
private val text by lazy {findViewById<TextView>(R.id.text)}
private val post by lazy {findViewById<TextView>(R.id.post)}
private val message by lazy {findViewById<TextView>(R.id.message)}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
post.setOnClickListener {
Handler(Looper.getMainLooper()).post {
text.text = "Post"
}
}
message.setOnClickListener {
object: Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
if(msg.what == 1000) {
text.text = "Message"
}
}
}.sendEmptyMessage(1000)
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Hello World!"
android:gravity="center"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/post"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Post Button"/>
<Button
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Message Button"/>
</LinearLayout>
'Android (안드로이드)' 카테고리의 다른 글
Android in A..Z - TextInputLayout (0) | 2021.01.20 |
---|---|
Android in A..Z - Glide (0) | 2020.11.07 |
Android in A..Z - Widget (0) | 2020.08.09 |
Android in A..Z - Activity Lifecycle (0) | 2020.07.28 |
Android in A..Z - Notification (0) | 2020.07.27 |