Skip to content

Instantly share code, notes, and snippets.

@byhankim
Last active April 8, 2021 05:34
Show Gist options
  • Save byhankim/b0d0179d054e465cad140935ccdf82c5 to your computer and use it in GitHub Desktop.
Save byhankim/b0d0179d054e465cad140935ccdf82c5 to your computer and use it in GitHub Desktop.
package com.thread.basic
import android.os.Bundle
import android.text.Editable
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import java.lang.Thread.sleep
class ThreadSimpleActivity : AppCompatActivity() {
private var backThreadValue1: Long = 0
private var backThreadValue2: Long = 0
private var mainThreadValue: Long = 0
//백그라운드에서 돌아 갈 쓰레드 선언
private var backGroundThread1: SimpleThreadOne? = null
// private var backGroundThread2: SimpleThreadTwo? = null
private var backGroundThread2: SimpleThreadImpl? = null
private lateinit var thread: Thread
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val mainInflater = LayoutInflater.from(this)
val layoutView: View = mainInflater.inflate(R.layout.thread_simple_1_layout, null)
setContentView(layoutView)
val btnThreadResult: Button = layoutView.findViewById(R.id.btn_thread_result)
val uiThreadIncrementBtn: Button = layoutView.findViewById(R.id.btn_ui_thread_increment)
//쓰레드 On/Off
val threadToggle: ToggleButton = layoutView.findViewById(R.id.btn_thread_toggle)
//textOn : 메세지 표시
threadToggle.isChecked = true
val mainEdit: EditText = layoutView.findViewById(R.id.main_edit)
val backEdit1: EditText = layoutView.findViewById(R.id.back_edit_1)
val backEdit2: EditText = layoutView.findViewById(R.id.back_edit_2)
//백그라운드 쓰레드를 On/Off 함
threadToggle.setOnClickListener {
if (!threadToggle.isChecked) {
/*
* Thread를 생성 시킴(1초/3초)
*/
backGroundThread1 = SimpleThreadOne("BACK_GROUND_THREAD_1", 1000L)
// backGroundThread2 = SimpleThreadTwo("BACK_GROUND_THREAD_2", 3000L)
backGroundThread1!!.start()
// runnable을 thread로
backGroundThread2 = SimpleThreadImpl(3000L)
thread = Thread(backGroundThread2)
thread.start()
(findViewById<TextView>(R.id.textView1)).text = " 쓰레드 스타트 됨! "
threadToggle.isChecked = false
} else {
mainEdit.setText("")
backEdit1.text = Editable.Factory.getInstance().newEditable(backGroundThread1!!.name + " 종료됨!")
backEdit2.text = Editable.Factory.getInstance().newEditable(thread.name + " 종료됨!")
backGroundThreadFinish()
(findViewById<TextView>(R.id.textView1)).text = "백 그라운드 쓰레드 종료 됨!"
threadToggle.isChecked = true
Toast.makeText(
this@ThreadSimpleActivity,
"Back Ground Thread가 종료 됩니다 ", Toast.LENGTH_SHORT
).show()
}
}
//터치 할 때 마다 Main-Thread에서 1씩 증가 함
uiThreadIncrementBtn.setOnClickListener {
++mainThreadValue
Toast.makeText(
this@ThreadSimpleActivity,
"Main_UI 에서는 클릭시 마다 1씩 증가 합니다", Toast.LENGTH_SHORT
).show()
}
//Main 과 Back Ground 에서 각각 증가된 값을 출력 함
btnThreadResult.setOnClickListener {
mainEdit.text =
Editable.Factory.getInstance()
.newEditable("""${Thread.currentThread().name} 클릭횟수 => $mainThreadValue""")
if (backGroundThread1 != null && backGroundThread2 != null &&
backGroundThread1!!.isAlive && thread.isAlive
) {
backEdit1.text = Editable.Factory.getInstance().newEditable(
backGroundThread1!!.name + " 증가값 => "
+ backThreadValue1
)
backEdit2.text = Editable.Factory.getInstance().newEditable(
thread.name + " 증가값 => "
+ backThreadValue2
)
} else {
Toast.makeText(
applicationContext,
"백그라운드 쓰레드가 활성화 되지 않았네요", Toast.LENGTH_LONG
).show()
}
}
}
//Back Key 또는 Activity가 전경으로 갈 때 동작
override fun onStop() {
super.onStop()
backGroundThreadFinish()
}
/*
* 백 그라운드 쓰레드를 종료 시킴
*/
private fun backGroundThreadFinish() {
if (backGroundThread1 != null) {
backGroundThread1!!.interrupt()
backGroundThread1 = null
backThreadValue1 = 0
}
// 초기화가 이루어졌는냐를 검사하여 비교할 수 있긴 할것같다
if (backGroundThread2 != null) { // 초기화가 이루어졌는냐를
thread.interrupt()
backGroundThread2 = null // lateinit : 실제 사용할 때 초기화. 그 전까진 쓰면안된다
backThreadValue2 = 0
}
}
inner class SimpleThreadOne(threadName: String?, delayTime: Long) : Thread(threadName) {
private var delayTime = delayTime
private var threadFinishFlag = false
override fun run() {
while (!threadFinishFlag) {
try {
sleep(delayTime)
++backThreadValue1
} catch (ie: InterruptedException) {
Log.e("InterruptedTag", "$name Thread 인터럽트 발생!")
threadFinishFlag = true // 여기서 플래그 변경
}
}
}
}
// private inner class SimpleThreadTwo(threadName: String?, delayTime: Long) : Thread(threadName) {
// private var delayTime = delayTime
// private var threadFinishFlag = false
// override fun run() {
// while (!threadFinishFlag) {
// try {
// sleep(delayTime)
// ++backThreadValue2
// } catch (ie: InterruptedException) {
// Log.e("InterruptedTag", "$name Thread 인터럽트 발생!")
// threadFinishFlag = true
// }
// }
// }
// }
// 더 많이 쓰는 방법
// runnable, impl, kotlin문법대로 러너블 상속
// 쓰레드 상속 아니므로 sleep이나 등등 각각 부분 처리 필요
// 안드로이드 스킬업 -> 쓰레드에 대한 이해
// 사실 람다 쓰는방법이 강력하긴 하다
// animation처리 frame by frame 직접처리할때 등 아주 많이 쓴다
// method가 하나밖에 없어서 러너블 -> 람다로 간략하게 표현하기도 매우 좋다
inner class SimpleThreadImpl(val delayTime: Long): Runnable {
private var threadFinishFlag = false
override fun run() {
while (!threadFinishFlag) {
try {
sleep(delayTime)
++backThreadValue2
} catch (ie: InterruptedException) {
Log.e("InterruptedTag",
"${Thread.currentThread().name} Thread 인터럽트 발생!")
threadFinishFlag = true
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment