๊พธ์ค€ํ•จ์ด ์ง„๋ฆฌ๋‹ค!!

์–ด์ œ๋ณด๋‹ค ๋ฐœ์ „ํ•œ ์˜ค๋Š˜์ด ๋˜๊ณ ํ”ˆ ๐Ÿง‘๐Ÿปโ€๐Ÿ’ป ์˜ ๋ธ”๋กœ๊ทธ

Android/Kotlin

[Kotlin][Android] ์•ˆ๋“œ๋กœ์ด๋“œ Coroutine(์ฝ”๋ฃจํ‹ด) ์‚ฌ์šฉํ•˜์—ฌ ๋กœ๋”ฉ ํ™”๋ฉด(๋‹ค์ด์–ผ๋กœ๊ทธ) ๋งŒ๋“ค๊ธฐ

๋ށ์š” 2022. 11. 1. 15:25

์•ˆ๋…•ํ•˜์„ธ์š” ๐Ÿ‘‹

์˜ค๋Š˜์€ ์ฝ”๋ฃจํ‹ด์„ ํ™œ์šฉํ•˜์—ฌ 

์•ˆ๋“œ๋กœ์ด๋“œ์—์„œ ๋กœ๋”ฉ ํ™”๋ฉด(๋‹ค์ด์–ผ๋กœ๊ทธ)์„ ๋งŒ๋“œ๋Š” ๋ฐฉ๋ฒ•์„

ํฌ์ŠคํŒ…ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค.

 

์ฝ”๋ฃจํ‹ด์˜ ๊ธฐ๋ณธ์ ์ธ ์„ค๋ช…๊ณผ ์‚ฌ์šฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” 

์•„๋ž˜ ํฌ์ŠคํŒ…๋“ค์— ์ž์„ธํ•˜๊ฒŒ ์„ค๋ช…๋˜์–ด ์žˆ์œผ๋‹ˆ ํ™•์ธ ๋ถ€ํƒ๋“œ๋ฆฝ๋‹ˆ๋‹ค ๐Ÿ˜Ž

 

 

[Kotlin] ์ฝ”ํ‹€๋ฆฐ Coroutine(์ฝ”๋ฃจํ‹ด)์— ๋Œ€ํ•˜์—ฌ (1) - CoroutineScope์™€ CoroutineContext ๋ฐ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฐฉ๋ฒ•

์•ˆ๋…•ํ•˜์„ธ์š” ์˜ค๋Š˜์€ ์ฝ”ํ‹€๋ฆฐ์˜ Coroutine์— ๋Œ€ํ•˜์—ฌ ํฌ์ŠคํŒ…ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. Coroutine์ด๋ž€? ํ”„๋กœ๊ทธ๋ž˜๋ฐ์—์„œ ํ•˜๋‚˜์˜ ์ž‘์—… ๋‹จ์œ„๋ฅผ Routine์ด๋ผ ํ•˜๋Š”๋ฐ ๊ฐ Routine์ด ํ˜‘์—…(Co)ํ•˜์—ฌ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ณผ์ •์„ ํ•ฉ์น˜๊ฒŒ

devyo-111commit.tistory.com

 

 

[Kotlin] ์ฝ”ํ‹€๋ฆฐ Coroutine(์ฝ”๋ฃจํ‹ด)์— ๋Œ€ํ•˜์—ฌ (2) - ์ฝ”๋ฃจํ‹ด Channel(์ฑ„๋„)

์•ˆ๋…•ํ•˜์„ธ์š” ์˜ค๋Š˜์€ ์ €๋ฒˆ ํฌ์ŠคํŒ…์— ์ด์–ด์„œ ์ฝ”๋ฃจํ‹ด Channel์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋ฃจํ‹ด์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฐฉ๋ฒ•์€ ์ด์ „ ํฌ์ŠคํŒ…์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ ํ•จ๊ป˜ ํ™•์ธํ•ด๋ณด์„ธ์š” :) [Kotlin] ์ฝ”

devyo-111commit.tistory.com

 

 

[Kotlin] ์ฝ”ํ‹€๋ฆฐ Coroutine์— ๋Œ€ํ•˜์—ฌ (3) - Coroutine Flow(ํ”Œ๋กœ์šฐ)

์•ˆ๋…•ํ•˜์„ธ์š”๐Ÿ‘‹ ์˜ค๋Š˜์€ ์ฝ”๋ฃจํ‹ด ๊ด€๋ จ ๋งˆ์ง€๋ง‰ ํฌ์ŠคํŒ…์œผ๋กœ ์ฝ”๋ฃจํ‹ด Flow์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ํฌ์ŠคํŒ…ํ•ด๋ณด๋ ค ํ•ฉ๋‹ˆ๋‹ค. 1. Coroutine Flow๋ž€? Flow๋Š” ์ˆœ์ฐจ์ ์œผ๋กœ ๊ฐ’์„ ๋‚ด๋ณด๋‚ด๊ณ  ์ •์ƒ์ ์œผ๋กœ ๋˜๋Š” ์˜ˆ์™ธ๋กœ ์™„๋ฃŒ๋˜

devyo-111commit.tistory.com

 

๋กœ๋”ฉ ํ™”๋ฉด์„ ๊ตฌ์„ฑํ•˜๋Š”๋ฐ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ 

์ œ๊ฐ€ ์ฑ„ํƒํ•œ ๋ฐฉ๋ฒ•์€ Coroutine Flow๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด์—ˆ์Šต๋‹ˆ๋‹ค.

 

1. ๋จผ์ € ๊ฐ„๋‹จํ•˜๊ฒŒ Progress์‹œ์— ํ™”๋ฉด์— ํ‘œ์‹œํ•  ๋‹ค์ด์–ผ๋กœ๊ทธ๋ฅผ ํ•˜๋‚˜ ๋งŒ๋“ค์–ด์ค๋‹ˆ๋‹ค.

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="200dp">
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/dialogText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="๋กœ๋”ฉ์ค‘์ž…๋‹ˆ๋‹ค.."
            android:textSize="30sp"
            android:gravity="center"
            />

        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_below="@+id/dialogText"
            style="@android:style/Widget.ProgressBar.Inverse"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="30dp" />
    </RelativeLayout>
</androidx.cardview.widget.CardView>

 

import android.app.Dialog
import android.os.Bundle
import com.coroutine.basic.databinding.DialogProgressBinding

class ProgressDialog(owner : MainActivity) : Dialog(owner) {

    private lateinit var binding : DialogProgressBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DialogProgressBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
    }
}

 

2. ๋‹ค์Œ์€ ํ‘œ์‹œํ•  ํ™”๋ฉด์„ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌ์„ฑํ•ด์ค๋‹ˆ๋‹ค.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/startBtn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="64dp"
        android:text="์‹œ์ž‘"
        android:textSize="25sp" />

    <TextView
        android:id="@+id/displayTV"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/startBtn"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:textColor="#FF8A80"
        android:textSize="25sp"
        android:textStyle="bold" />

</RelativeLayout>

 

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.coroutine.basic.databinding.ActivityMainBinding
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
    private lateinit var binding : ActivityMainBinding
    private lateinit var startFlow : kotlinx.coroutines.flow.Flow<Int>

    private lateinit var mProgressDialog: ProgressDialog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater).also {
            setContentView(it.root)
        }
        mProgressDialog = ProgressDialog(this) // Dialog ์ƒ์„ฑ
        addListeners()
    }

    private fun addListeners() {
        with(binding){
            startBtn.setOnClickListener {
                if(::mProgressDialog.isInitialized){ // Dialog๊ฐ€ ์ดˆ๊ธฐํ™” ๋์„๋•Œ ํ‘œ์‹œ
                    mProgressDialog.show()
                }
                CoroutineScope(Dispatchers.Default).launch{
                    onClickStart()
                }
                CoroutineScope(Dispatchers.Main).launch {
                    startFlow.collect{ 
                    //Flow์—์„œ ์ „๋‹ฌ ๋ฐ›์€ ๊ฐ’์„ main Dispatcher์—์„œ TextView์— ์—…๋ฐ์ดํŠธ
                        binding.displayTV.text = "Progressing ${it*10}%"
                    }
                }
            }
        }
    }

    private suspend fun onClickStart() { // ์‹œ์ž‘ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ ธ์„๋•Œ progress์ฆ๊ฐ€ 
        var value = 0
        startFlow  = flow {
            while (value < 10){ //10์ด ๋˜๋ฉด loop ๋น ์ ธ๋‚˜์˜ค๊ธฐ
                delay(1000)
                value++
                emit(value) //Flow์— ๊ฐ’์„ emit

            }
            CoroutineScope(Dispatchers.Main).launch { 
            //loop(๊ธฐ๋‹ค๋ ค์•ผํ•  ๋™์ž‘)๊ฐ€ ๋๋‚˜๋ฉด Dialog ๋‹ซ๊ธฐ
                mProgressDialog.dismiss()
            }
        }

    }
}

 

์ฝ”๋“œ๋Š” ์œ„์™€ ๊ฐ™์œผ๋ฉฐ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ € while๋ฌธ์— ํ•ด๋‹น ํ•˜๋Š” ๋ถ€๋ถ„์— ์ฒ˜๋ฆฌ๋ฅผ ๊ธฐ๋‹ค๋ ค์•ผ ํ•˜๋Š” ๋™์ž‘ (Rest ์ฒ˜๋ฆฌ , DB ์ฝ๊ธฐ , Download ๋“ฑ)์œผ๋กœ ๋Œ€์ฒดํ•˜์—ฌ

๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๐Ÿค”

 

๋งˆ์ง€๋ง‰์œผ๋กœ ์‹คํ–‰ํ™”๋ฉด ์ฒจ๋ถ€ํ•˜๋ฉฐ ํฌ์ŠคํŒ… ๋งˆ์น˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์˜ค๋Š˜๋„ ์ฆ์ฝ”ํ•˜์„ธ์š” :)