개발/Android

비동기처리에서 특정 기능들만 순서대로 처리하기

이도일 2022. 3. 23. 14:40

업데이트 쳐내느라 새로 알게된거 하나도 정리 안 했다..ㅎ

어쨌든 대충 테스트배포 끝냈으니 기억을 위해 기록한다.

 

 

 

 

적어도 통신을 이용하는 어플리케이션을 개발하다보면,

통신에 관련된 것을 전부 비동기로 처리하게 된다.

당연함....동기로 하면 괴오래걸림;;

그러나 가끔은 몇 개를 순서대로 처리해야 할 일이 생긴다.

예를 들면 뭐 1번의 값을 받아온 후에 2번이 돌아가야한다던지...

그럴때를 위한 기능들이다.

 

 

 

1. withContext  : 해당 작업을 끝낼 때 까지 코루틴을 일시정지하기 위해 사용한다

- async와 동일한 결과값을 반환한다
- async{ }.await() 과 유사
- 코루틴 내부나 susfend 함수 안에서 구현이 가능
- 콜백이 필요 없이 코드의 쓰레드 풀을 제어할 수 있기 때문에 네트워크 요청이나 DB 조회 같은 작업에 주로 사용
2. suspend function : 일시정지 / 재개를 위한 메소드

 - 코루틴 안에서만 사용되는 전용 메소드

 

어차피 기록용이니까 바로 코드부터 쓴다.

 

 

 

 

  withContext(Dispatchers.IO) {
                    setClubPostImage(piImagePath!!)
                }?.let { filePath ->

이런식으로 사용한다.

withContext를 이용해 코루틴을 일시정지한뒤,

저 filePath를 반환 받을 때 까지 setClubPostImage(piImagePath!!)를 실행한다.

리턴값으로 패스가 넘어오면, 그 이후에 저 값을 이용해서 다음 루틴을 재개한다.

 

 

 

여기서 사용되는 Dispatcher의 종류는

Dispatchers.Main
 : 안드로이드의 메인 쓰레드로, UI 작업을 위해 사용.(UI를 구성,  LiveData를 업데이트 등)

Dispatchers.IO
 : 네트워크, 디스크 I/O 실행에 최적화됨. (Retrofit으로 네트워크 통신, File/Room DB에서 데이터 읽고/쓸 때)

Dispatchers.Default
 : CPU 사용량이 많은 무거운 작업 처리에 최적화 됨. (데이터 가공 / 복잡한 연산, JSON 파싱을 할 때)

요렇게 있다.

나는 서버에서 리스트를 긁어오는 기능이 중간에 필요했으므로 두 번째로 처리했다.

 

 

 

 

다음으로,

setClubPostImage(piImagePath!!)의 내부는 다음과 같다.

    private suspend fun setClubPostImage(imagePath: String): String? {
        return try {
//            Dlog.d("setClubPostImage imagePath = $imagePath")
            val resizeImageFile = File(saveBitmap(getResizePicture(imagePath)))
            val key = MemberUtil.getMemberKeyPair()
            val data = repository.setClubPostImage(
                resizeImageFile,
                key.first,
                key.second
            )

//            Dlog.d("setClubPostImage data = $data")
            if (data.result == ResultCode.SUCCEED) {
                data.aData[0].FilePath
            } else {
                handleInsertPost = false
                val msg = data.msg
                _insertPost.postValue(Resource.error(msg, null))
                null
            }
        } catch (e: Exception) {
            Dlog.e("setClubPostImage error = $e")
            null
        }
    }

해당하는 값이 제대로 들어오면 path return하고, 

안들어오면 null이다.

끝.