Android/Coroutine
${Harvey}
2022. 11. 22. 17:50
2022. 11. 22. 17:50
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val goToSecond = findViewById<Button>(R.id.gotoSecond)
goToSecond.setOnClickListener{
val intent = Intent(this,SecondActivity::class.java)
startActivity(intent)
}
}
}
class SecondActivity : AppCompatActivity() {
lateinit var viewModel: SecondViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
viewModel = ViewModelProvider(this).get(SecondViewModel::class.java)
viewModel.a()
viewModel.b()
}
}
class SecondViewModel : ViewModel(){
fun a(){
CoroutineScope(Dispatchers.IO).launch{
for(i in 0..10){
delay(1000)
Log.d("SecondViewModel A",i.toString())
}
}
}
fun b(){
viewModelScope.launch {
for(i in 0..10){
delay(1000)
Log.d("SecondViewModel B",i.toString())
}
}
}
}
결과: ViewModelScope는 Activity가 종료되면 즉시 중단되지만 CoroutineScope는 Activity가 종료되어도 지속된다.
${Harvey}
2022. 11. 22. 17:49
2022. 11. 22. 17:49
기존에는 비동기식 프로그램을 순차적으로 해결하기위해 아래와 같이 코드를 작성해야했다.(CallBack Hell)
콜백지옥.
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val api = RetrofitInstance.getInstance().create(MyApi::class.java)
// 1. 유저 정보를 가져와서 (userId)
api.getPost1().enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: Response<Post>) {
Log.d("API1", response.body().toString())
// 2. userId 기반으로 데이터를 가져오고 가져온 닉네임값
api.getPostNumber(2).enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: Response<Post>) {
Log.d("API2", response.body().toString())
// 3. 닉네임 기반으로 데이터를 가져오고 유저의 댓글을 가져와서
api.getPostNumber(3).enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: Response<Post>) {
Log.d("API3", response.body().toString())
// 4. 유저의 댓글 기반으로, 대댓글
api.getPostNumber(4).enqueue(object : Callback<Post> {
override fun onResponse(call: Call<Post>, response: Response<Post>) {
Log.d("API4", response.body().toString())
}
override fun onFailure(call: Call<Post>, t: Throwable) {
Log.d("API4", "fail")
}
})
}
override fun onFailure(call: Call<Post>, t: Throwable) {
Log.d("API3", "fail")
}
})
}
override fun onFailure(call: Call<Post>, t: Throwable) {
Log.d("API2", "fail")
}
})
}
override fun onFailure(call: Call<Post>, t: Throwable) {
Log.d("API1", "fail")
}
})
}
}
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.0")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.4.1")
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("TEST","START")
CoroutineScope(Dispatchers.IO).launch{
Log.d("TEST","CoroutineScope START")
a()
b()
Log.d("TEST","CoroutineScope END")
}
Log.d("TEST","END")
}
//START ->END ->AP1 ->BP1 -> AP2 ->BP2
suspend fun a(){ //suspend:유예하다.
//a작업 2초정도 걸림.
delay(1000)
Log.d("TEST","AP1")
delay(1000)
Log.d("TEST","API2" )
}
suspend fun b(){
//B작업 2초정도 걸림.
delay(1000)
Log.d("TEST","BP1")
delay(1000)
Log.d("TEST","BPI2" )
}
}
Coroutine은 일시중단 가능하다. Coroutine이 일시중단 되려면 수행되는 위치 또한 코루틴 내부여야 하기에
외부에 suspend fun(일시중단 가능 함수)로 만들어 사용하거나 로직을 Coroutine내부로 옮겨 사용해야한다.