개발/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이다.
끝.