Android Jetpack

Simple Coroutine - 3 (ViewModelScope)

----___<<<<< 2022. 2. 14. 21:16

개복치개발자 강의는 아래의 링크에서 확인할 수 있습니다.

 

개복치개발자 | Linktree

uyalae@naver.com

linktr.ee

 

 이전에 코루틴은 JETPACK 항목들과 함께 사용할 수 있다고 말씀드렸습니다.

 

 그렇다면 Lifecycle 즉 ViewModel과 어떻게 사용되는지 한번 살펴보겠습니다.

 

 일단 코루틴과 lifecycle-viewmodel을 gradle에 넣어주고 한번 시작해보겠습니다.

 

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.0"

 

 간단하게 MainActivity를 만들었습니다.

 

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val testBtn = findViewById<Button>(R.id.goToSecond)
testBtn.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
val testBtn2 = findViewById<Button>(R.id.goToThird)
testBtn2.setOnClickListener {
val intent = Intent(this, ThirdActivity::class.java)
startActivity(intent)
}
}
}
view raw MainActivity.kt hosted with ❤ by GitHub
<?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"
tools:context=".MainActivity">
<Button
android:id="@+id/goToSecond"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="goToSecond" />
<Button
android:id="@+id/goToThird"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="goToThird" />
</LinearLayout>

 SecondActivity / ThirdActivity로 이동해서 각각에 대해서 구현해보겠습니다.

 

 

 우선 SecondActivity는 Thread 시작과 Activity를 종료할 수 있는 애로 나눠놨습니다.

 

 그런데 여기서 문제가 생깁니다.

 

 Acticity가 종료되면 Thread를 종료해야 하는데 계속 Thread가 살아서 Log를 찍는 부분이 보입니다.

 

class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val testThread = SimpleThread()
val threadStart = findViewById<Button>(R.id.threadStart)
threadStart.setOnClickListener {
testThread.start()
}
val activityFinish = findViewById<Button>(R.id.activityFinish)
activityFinish.setOnClickListener {
finish()
}
}
}
class SimpleThread() : Thread() {
override fun run() {
for(i in 1..100) {
Log.d("SecondActivity", "START : $i")
sleep(1000)
Log.d("SecondActivity","END")
}
}
}
<?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"
tools:context=".SecondActivity">
<Button
android:id="@+id/threadStart"
android:text="threadStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/activityFinish"
android:text="activityFinish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

 자, 그렇다면 이 문제를 해결하기 위해서 ThirdActivity를 만들어봅니다.

 

 ViewModel에서 viewModelScope.lauch 라고 해서 LifeCyCle을 연동해봅니다.

 

class ThirdActivity : AppCompatActivity() {
private lateinit var viewModel : ThirdViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_third)
viewModel = ViewModelProvider(this).get(ThirdViewModel::class.java)
val start = findViewById<Button>(R.id.start)
start.setOnClickListener {
viewModel.test()
}
val end = findViewById<Button>(R.id.end)
end.setOnClickListener {
finish()
}
}
}
class ThirdViewModel : ViewModel() {
fun test() = viewModelScope.launch {
for(i in 0..100) {
Log.d("ThirdViewModel","START $i")
delay(1000)
Log.d("ThirdViewModel","END")
}
}
}

 

 이렇게 하면, Activity가 종료되면 반복문이 종료됩니다.