반응형
[안드로이드] Thread, Thread간 통신/ Handler, Looper의 개념
참고 1. 성빈랜드님 글 안드로이드 스레드에 대해 한 번에 알아보자 AndroidDeepDive #1 — thread, message, message queue, looper, handler sungbin.land 2. https://hungseong.tistory.com/26 [Android, Kotlin] 멀티 스레드 간 통신
developerpearl.tistory.com
Thread, Handler, Looper에 대해서 알아보았는데, 이제 얘네를 직접 구현해보도록하겠습니다.
예제로는 버튼 Start를 누른 후부터의 시간 재는 기능으로 구현하겠습니다.
워커스레드 : Main Thread외에 추가된 Thread 구현
Toast메세지와 UI 수정을 위해서 context와 TextView를 parameter로 받아왔습니다.
** 여기서 중점으로 봐야하는 부분은 Handler(Looper.getMainLooper()).post 입니다.
여기 내부에서 UI 부분을 처리할 수 있습니다.
class TimeCountThread(val handler: Handler, val context : Context, val tv : TextView) : Thread() {
private var time = 0
override fun run() {
while(true) {
// 메세지 객체 전달.
val msg = handler.obtainMessage()
val bundle = Bundle()
bundle.putInt("key", time)
msg.data = bundle
handler.sendMessage(msg)
// post로 runnable 실행
Handler(Looper.getMainLooper()).post {
Toast.makeText(context, "시작 Tread : ${this.name}", Toast.LENGTH_SHORT).show()
// 다른 thread에서 UI에 접근하려하면 ANR발생한다.(Application Not Response
tv.text = "$time 초"
time += 5
}
sleep(5000)
}
}
fun stopThread(){
Handler(Looper.getMainLooper()).post{
Toast.makeText(context, "종료 Tread : ${this.name}", Toast.LENGTH_SHORT).show()
tv.text = "준비중"
}
}
}
* Fragment 내부에 구현했기때문에, onViewCreated 내부는 다음과 같습니다.
class FirstFragment : Fragment() {
private var _binding: FragmentFirstBinding? = null
private var timeCountThread: TimeCountThread? = null
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
// 메시지 처리 작업 수행
println("메세지 처리 작업 수행")
println(msg.data.getInt("key"))
}
}
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = FragmentFirstBinding.inflate(inflater, container, false)
return binding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.buttonFirst.setOnClickListener {
// 스레드 실행
if(timeCountThread==null) {
timeCountThread = context?.let { it1 ->
TimeCountThread(
handler,
it1, binding.textviewFirst
)
}
timeCountThread?.start()
}
// findNavController().navigate(R.id.action_FirstFragment_to_SecondFragment)
}
// 스레드 중지
binding.buttonSecond.setOnClickListener {
timeCountThread?.stopThread()
timeCountThread=null
}
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
}
위 버튼을 누르면 시간이 흘러갑니다. 5초마다 갱신~!
아래 버튼을 누르면 멈춥니다.
반응형
'안드로이드' 카테고리의 다른 글
[안드로이드] View.post() : 실행시점을 알아보자 (0) | 2023.03.29 |
---|---|
[안드로이드] Thread, Thread간 통신/ Handler, Looper의 개념 (0) | 2023.03.21 |
[안드로이드] 2-2. WebView 웹뷰 - Javascript Interface(Kotlin) (0) | 2023.03.11 |
[안드로이드] 2-1. WebView 웹뷰 - 로컬 HTML불러오기 (Kotlin) (0) | 2023.03.11 |
[안드로이드] 1. WebView 웹뷰- 띄우기 (Kotlin) (0) | 2023.03.11 |
댓글