티스토리 뷰

728x90

 


동기 & 비동기

1. 동기

• 요청을 보낸 후 응답을 기다린다.

• 기다리는 동안 다른 작업을 하지 않고, 응답이 오면 다시 작업을 시작한다.

• 관리가 쉽다.

• 요청한 작업을 하는 동안 아무 일도 하지 않고 기다려야할 때 사용한다.

 

2. 비동기

• 요청을 보낸 후 응답을 기다리는 동안에도 다른 작업을 계속 한다.

• 흐름이 하나 더 생기는 것이므로 관리가 어렵다.

• 작업 요청을 해놓고 사용자가 뒤로가기 버튼을 눌러서 작업을 취소하거나 했을 때의 대처가 필요하다.

• 비동기 처리 방식을 잘 사용할 수 있도록 해주는 라이브러리가 있다. -> Coroutine (코루틴)

• AsyncTask 클래스가 존재했지만 deprecated 되었다.

     -> 비동기를 이해하기 위해 우선 사용해보자.

 

3. AsyncTask로 비동기 동작 확인

• activity_sync_async13.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat 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=".SyncAsync_13"
    android:orientation="vertical">

    <TextView
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#AAAAFF"
        android:gravity="center"
        android:text="시작"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#AAFFAA"
        android:gravity="center"
        android:text="중지"
        android:textSize="30dp" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="50dp" />

    <TextView
        android:id="@+id/progressText"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:text="0%"
        android:textSize="30dp" />

    <TextView
        android:id="@+id/printLog"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#AAFFFF"
        android:gravity="center"
        android:text="로그 출력"
        android:textSize="30dp" />

</androidx.appcompat.widget.LinearLayoutCompat>

 

• SyncAsync_13.kt

package com.example.fastcampus

import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.ProgressBar
import android.widget.TextView

class SyncAsync_13 : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_sync_async13)

        val backgroundAsyncTask = BackgroundAsyncTask(findViewById(R.id.progressBar), findViewById(R.id.progressText))

        findViewById<TextView>(R.id.start).setOnClickListener { // 시작 누르면
            backgroundAsyncTask.execute() // 비동기 작업 시작
        }

        findViewById<TextView>(R.id.stop).setOnClickListener { // 중지 누르면
            backgroundAsyncTask.cancel(true) // 비동기 작업 중지
        }

        findViewById<TextView>(R.id.printLog).setOnClickListener { // 로그 출력 누르면
            Log.d("testt", "print log") // Logcat에 print log 출력
        }
    }
}

class BackgroundAsyncTask(val progressBar: ProgressBar, val progressText: TextView): AsyncTask<Int, Int, Int>() {
    // Params : doInBackground에서 사용할 자료형
    // Progress : onProgressUpdate에서 사용할 자료형
    // Result : onPostExecute에서 사용할 자료형

    var percent: Int = 0

    override fun doInBackground(vararg p0: Int?): Int {
        // 백그라운드에서 작업할 코드
        while (isCancelled() == false) {
            percent++
            if (percent > 100) break
            else publishProgress(percent)
            Thread.sleep(50)
        }
        return percent
    }

    override fun onPreExecute() {
        // 백그라운드 작업 전 실행할 코드
        percent = 0
        progressBar.setProgress(percent)

    }

    override fun onPostExecute(result: Int?) {
        // 백그라운드 작업 후 실행할 코드
        progressText.text = "작업이 완료되었습니다."
    }

    override fun onProgressUpdate(vararg values: Int?) {
        progressBar.setProgress(values[0] ?: 0)
        progressText.text = "퍼센트 : " + values[0]
    }

    override fun onCancelled() {
        // 백그라운드 작업이 취소됐을 경우 실행할 코드
        progressBar.setProgress(0)
        progressText.text = "작업이 취소되었습니다."
    }
}

프로그래스 바와 퍼센트가 올라가는 작업이 끝날 때까지 기다리지 않고, 작업 도중에 로그 출력을 눌러도 로그가 출력된다. (퍼센트를 올리는 일과 로그 출력이 비동기 방식으로 동작했기 때문이다.)

 

 

 

 

 

 

 

 

 

이 글은

패스트 캠퍼스 Android 앱 개발의 정석 with Kotlin 올인원 패키지 Online

강의를 듣고 공부한 내용을 바탕으로 작성되었습니다.

 


728x90
댓글
공지사항