마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

lifecycleScope.launch(Dispatchers.IO) {} 작업 완료시 완료했다는 신호를 주고 받는 코드

0 추천

성경 본문 검색 기능의 성능을 개선하고 있는 중입니다. 개선은 성공적이었습니다.

하지만, 프리미엄폰에서는 searchActivity를 켠 후, 검색버튼을 바로 눌러도 되는데,

자급제 폰에서는 searchActivity를 켠 후,

0.6~1초 정도 지난 후에 검색버튼을 눌러야 안튕기더라구요.

 

중괄호 내부에 텍스트를 읽어와서 ArrayList 변수에 저장하는 코드가 있는데,

이 속도가 매 번 제각각이어서 그렇습니다.

텍스트를 다 읽어오기 전에 검색 버튼을 누르면 튕깁니다.

그래서 스레드 작업이 끝나면 끝났다는 신호좀 보내줬으면 좋겠는데,

신호를 보내주는 코드랑 이걸 감지하는 코드가 뭔지 잘 모르겠어요.

 

텍스트 읽어오는 동안에는 터치를 못하게, UI를 감췄다가, 신호를 감지하면,

UI를 비저블 트루로 해놓으려고 합니다.

 

UI 속성 건드리는 작업은 이 중괄호 내부에서는 사용할 수 없더라구요.

그래서, 밖으로 신호를 좀 줬으면 좋겠다 싶어요.

일단 답변을 좀 더 읽어봐야 알것 같아요. ㅎ 감사합니다.

 

온 크리에이트 영역 
        lifecycleScope.launch(Dispatchers.IO) {
            //start_Time = System.currentTimeMillis()
            for (i in 1..2) {
                when (i) {
                    1 -> {
                        rp1 = "구약"
                        for (o in 0..38) {
                            rp2 = book3[o]              //1. 창세기
                            for (p in numbers1[o]) {    //1..50
                                rp3 = "${book5[o]}$p"   //genesis
                                loadDataSource(book1[o], p)      //창세기
                            }
                        }
                    }
                    2 -> {
                        rp1 = "신약"
                        for (o in 0..26) {
                            rp2 = book4[o]              //1. 마태복음
                            for (p in numbers2[o]) {    //1..28
                                rp3 = "${book6[o]}$p"   //matthew
                                loadDataSource(book2[o], p)      //마태복음
                            }
                        }
                    }
                }
            }
            uiShow()
            //end_Time = System.currentTimeMillis()
        }


온 크리에이트 외부 영역
    private fun uiShow () {
        tab_lay2.visibility = View.VISIBLE
        edit_layout.visibility = View.VISIBLE
        //액티비티 시작할때, 키보드 바로 보여주는 코딩.
        val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY)
    }

 

상쾌한 (1,890 포인트) 님이 2021년 4월 10일 질문
상쾌한님이 2021년 4월 10일 수정

1개의 답변

+1 추천
 
채택된 답변

코루틴 빌더 중에 대표적으로 많이 쓰는 게 launch와 async 입니다. luanch는 말그대로 실행해놓고 보는 개념이고, async는 응답이 올 때까지 대기해야 할 경우 쓰는 개념입니다. 따라서 async는 API를 호출하거나 동시에 여러개의 suspend 함수를 호출하고 모두 다 끝날 때까지 대기해야하는 경우에 대표적으로 많이 사용합니다.

lifecycleScope.launch  {
    showProgress()
    val searchResult = search(...)
    handleSearchResult(searchResult)
    hideProgress()
}

// withContext는 같은 Coroutine Scope에서 다른 쓰레드로 전환할 때 사용
// 다른 쓰레드에서 실행되더라고 코루틴은 함수가 끝날 때까지 대기한다. (Structured Concurrency라고 불리는 기능)
private suspend search(query: String) = witContext(Dispatcher.IO): Result<SearchData> {
      //검색해서 결과를 리턴
}

private fun handleSearchResult(result: Result<SearchData>) = withContext(Dispatcher.IO) {
     //검색결과를 처리
}

 

그리고 코루틴의 경우는  취소와 예외 처리가 직관적이지 않은 상당히 번거로운 문제가 있기 때문에 search() 함수에서는 에러를 던지시지 말고 에러를 나타나는 sealed class를 사용하는게 일반적입니다.

sealed class Result<out T> {
    data class Success<T>(val data: T): Result<T>()
    data class Error(val message: String): Result<Nothing>()
}


private suspend fun serarch(query: String): Result<SearchData> = withContext(Dispatcher.IO) {
   try {
        val data: SearchData = apiCall()
       if (data가 문제 없다면)  {
           return@withContext Result.Success(data);
       }

        Result.Error("에러원인")
    } catch (e: Exception) {
         Result.Error("에러원인")
    } 

    // 또는 에러 체크하는 로직을 넣어서 맞는 타입을 리턴
}

when (val result = search("test")) {
    is Result.Error -> print(result.message)
    is Result.Success -> println(reulst.data)
}

 

spark (226,420 포인트) 님이 2021년 4월 10일 답변
spark님이 2021년 4월 10일 수정
아직 잘 모르겠네요. 좀 살펴보고 오겠습니다. ^^; 답변 감사합니다.
코루틴이 딱 보기에는 쉬운데 작업취소와 에러처리같은 경우를 생각해야 해서 이 부분에 가면 좀 골치가 아파요. 다행히 안드로이드에서는 제공하는 lifecycleScope, viewModelScope같은 경우는 라이프사이클이 종료되면 자동 취소하도록 처리를 해놨기 때문에 가능하면 그녀석들을 사용하면 좋아요.
withContext이게 단서 같아요. ^^ 공부하고 오겠습니다. 감사합니다.
...