Mặc định logic code của chúng ta viết sẽ chạy trên Main Thread, hay còn gọi là UI Thread. Nếu có logic code nào đó chạy quá chậm (I/O, thực thiện quá nhiều tính toán, xem thêm) sẽ khiến UI Thread bị chặn vì giao diện không thể phản hồi lại khi chưa thực hiện xong logic code đó, hệ thống sẽ hiện thị hộp thoại ARNs, gây khó chịu cho người dùng.
Vì vậy, những logic code cần nhiều thời gian để hoàn thành nên được chạy trong một Theard khác, khi nào thực hiện xong sẽ báo lại kết quả cho UI Thread.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) for (i in 0 until length){ if (i == length-1){ text_view.text = "Loaded" } } Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show() } }
Màn hình sẽ trắng xóa như thế này cho tới khi chạy xong vòng for:
Mãi mới xong :3
(Đừng thắc mắc time trong hình, mình chạy mấy lần mới chụp màn hình đúng lúc được).
Nếu chạy vòng for đó trong Thread khác thì sao? Chịu khó đọc tiếp bên dưới.
override fun run() { for (i in 0 until length){ if (i == length-1){ runOnUiThread { text_view.text = "Loaded" theard.join() } } } }
}
}
App run lên cái hiện như này luôn, vòng for sẽ chạy trong Thread riêng:
Lúc vòng for chạy xong rồi sẽ setText() mới cho text_view:
Nếu thắc mắc tại sao phải setText() trong runOnUiThread(), thì hãy nhớ ta đang setText() trong 1 luồng không phải UI Theard, do đó nếu muốn thay đổi UI, phải chạy trong UI Theard.
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) object : Thread() { override fun run() { for (i in 0 until length){ if (i == length-1){ runOnUiThread { text_view.text = "Loaded" this.join() } } } } }.start() Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show() }
}
Sự khác biệt giữa Implement Runnable và Extend Thread:
* Khi Implement Runnable, vì Runnable là Interface, nên ta có thể Extend thêm Class khác * Khi Extend Thread, vì Thread là một Class, không thể Extend thêm Class khác