2017-11-02 3 views
1

나는 콜린 (Kotlin) 코 루틴을 사용하여 백그라운드에서 무거운 작업을 수행하려고합니다.Kotlin coroutines CalledFromWrongThreadException

하지만이 오류 메시지를 받았습니다,

'android.view.ViewRootImpl $ CalledFromWrongThreadException :. 견해를 만질 수있는 뷰 계층 구조를 생성 만 원래 스레드'

fun setList() { 
    media_image_list.adapter = imageListAdapter 
    ... 

    launch { 
     val images = getImages(galleryPath) 
     imageListAdapter.setItems(images) 
    } 
} 




suspend private fun getImages(): MutableList<Image> { 
    val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI 
    ... 
} 

어떻게 제대로 백그라운드에서 실행 만드는 방법?

+0

Coroutine을 다음과 같이 'Unconfined'모드로 실행 해보십시오 : 'launch (Unconfined)'? – s1m0nw1

+0

@ s1m0nw1 작동합니다. UI와 관련된 작업이 작동하는 경우 Unconfined를 사용해야합니까? –

답변

1
나는 다음과 같은 방법으로 그것을 해결하기 위해 제안

다음 코 루틴을 실행 항상 그런

// explicitly request it to be executed in bg thread 
suspend private fun getImages(): MutableList<Image> = withContext(CommonPool) { 
    val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI 
    ... 
} 

:

첫째, 명시 적으로이 같은 withContext 기능을 사용하여 백그라운드 스레드에 당신의 "무거운 작업을"오프로드 UI 스레드에서보기 또는 다른 UI 개체를 만지기 :

launch(UI) { 
    val images = getImages(galleryPath) 
    imageListAdapter.setItems(images) 
} 
+0

'(CommonPool)을 실행하지 않고도 할 수 있습니까?' 그것없이 백그라운드 스레드에서 실행되지 않을까요? –

+0

'run (CommonPool)'을 생략하면'getImages' 코드가 UI 스레드에서 실행됩니다. 'getImages'가 _asynchronous_ non-blocking API를 사용한다면 괜찮습니다. 그러나 스레드를 차단하는 API를 사용한다면 Ok입니다. –