2017-11-02 21 views
1

私はバックグラウンドでいくつかの重い仕事を実行するためにコトリンコルーチンを使用しようとしています。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

は、次のような 'Unconfined'モードでコルーチンを実行しようとするだろうか? – s1m0nw1

+0

@ s1m0nw1うまくいきます。UIに関連する仕事がうまくいけばUnconfinedを使う必要がありますか? –

答えて

1

私は次のようにそれに対処することをお勧め:

まず、明示的にこのようwithContext機能を使用してバックグラウンドスレッドにあなたの「重い仕事を」オフロード:

// 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 
    ... 
} 

すると、常にコルーチンを実行しますそのタッチUIスレッド内のビューまたは他のUIオブジェクト: `打ち上げ(一軸)`:

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

「(CommonPool)を実行しない」だけでもいいですか?それがなければ、バックグラウンドスレッドで実行されませんでしたか? –

+0

'run(CommonPool)'を省略すると、 'getImages'コードがUIスレッドで実行されます。あなたの 'getImages'が_asynchronous_ノンブロッキングAPIを使用するのはOKですが、スレッドをブロックするAPIを使用する場合はOKではありません。 –

関連する問題