2017-12-20 30 views
3

runblocking의 목적은 무엇입니까? OnClickListener?에서 사용할 수 있습니까? 내가 OnClickListener를
에 runblocking을 {} 사용하고 여기에 이것은 내가 출시 (UI) {} 대신 출시를 사용하는 경우 그것은이단추를 클릭 할 때 runblocking을 사용하는 방법

12-20 14:46:31.387 26915-26915/ I/System.out: before1 
12-20 14:46:31.399 26915-26915/ I/System.out: in async1 
12-20 14:46:31.405 26915-26915/ I/System.out: Hello, 
12-20 14:46:31.405 26915-26915/ I/System.out: after hello1 
12-20 14:46:32.410 26915-26937/I/System.out: World!1561 
12-20 14:46:32.422 26915-26937/ E/AndroidRuntime: FATAL EXCEPTION: 
ForkJoinPool.commonPool-worker-2 

    android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views. 
     at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6556) 
     at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:907) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.view.View.requestLayout(View.java:18728) 
     at android.widget.TextView.checkForRelayout(TextView.java:7169) 
     at android.widget.TextView.setText(TextView.java:4347) 
     at android.widget.TextView.setText(TextView.java:4204) 
     at android.widget.TextView.setText(TextView.java:4179) 
     at MainActivity$onCreate$1$1$job$1.doResume(MainActivity.kt:164) 
     at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:54) 
     at kotlinx.coroutines.experimental.DispatchTask.run(CoroutineDispatcher.kt:123) 
     at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1388) 
     at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:251) 
     at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:845) 
     at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1674) 
     at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1629) 
     at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:108) 

12-20 14:46:36.410 26915-26915/I/System.out: after runBlocking1 
12-20 14:46:36.410 26915-26915/ I/Choreographer: Skipped 313 frames! The 
application may be doing too much work on its main thread. 

같은 오류를 보여줍니다 내 코드

mBinding.ivAdd.setOnClickListener{ 
println("before" + Thread.currentThread().id) 
     runBlocking { 
      println("in async" + Thread.currentThread().id) 

      val job = launch { 
       // launch new coroutine and keep a reference to its Job 
       delay(1000L) 
       println("World!" + Thread.currentThread().id) 
       mBinding.tvNoDataFound.text = "test" 
      } 
      println("Hello,") 
      println("after hello" + Thread.currentThread().id) 
      delay(5000) 
      job.join() // wait until child coroutine completes 
     } 
     println("after runBlocking" + Thread.currentThread().id) 
    } 

입니다 {}, 출력은 아래와 같습니다.

12-20 14:57:11.700 27338-27338/ I/System.out: before1 
12-20 14:57:11.710 27338-27338/ I/System.out: in async1 
12-20 14:57:11.714 27338-27338/ I/System.out: Hello, 
12-20 14:57:11.714 27338-27338/ I/System.out: after hello1 
12-20 14:57:16.718 27338-27338/ I/art: Note: end time exceeds epoch: 

다른 코 루틴에서 온 "세계"를 인쇄하지 않습니다. 여기

은 마지막으로 그것을에서 인쇄 "runblocking 후"에서 onCreate() 위의 코드의

println("before runblocking " + Thread.currentThread().id) 
     runBlocking { 
      println("in runblocking " + Thread.currentThread().id) 

      val job = launch(UI) { 

       println("In launch " + Thread.currentThread().id) 

      } 
      println("after launch " + Thread.currentThread().id) 

     } 
     println("after runBlocking " + Thread.currentThread().id) 

출력이

12-20 15:58:13.253 8588-8588/? I/System.out: before runblocking 1 
12-20 15:58:13.266 8588-8588/? I/System.out: in runblocking 1 
12-20 15:58:13.271 8588-8588/? I/System.out: after launch 1 
12-20 15:58:13.273 8588-8588/? I/System.out: after runBlocking 1 
12-20 15:58:13.363 8588-8588/? I/System.out: In launch 1 

우리가 기대 그대로에서 runblocking 사용 runblocking의 또 다른 예이다 하지 않습니다. 나는 서브 코 루틴의 완료를 기다리는 job.join를 사용하는 경우 는 위의 코드는 코드의

println("before runblocking " + Thread.currentThread().id) 
     runBlocking { 
      println("in runblocking " + Thread.currentThread().id) 

      val job = launch(UI) { 
       println("In launch " + Thread.currentThread().id) 
      } 
      println("after launch " + Thread.currentThread().id) 
      job.join() // wait until child coroutine completes 
     } 
     println("after runBlocking " + Thread.currentThread().id) 

출력은 다음

12-20 16:10:43.234 9194-9194/ I/System.out: before runblocking 1 
12-20 16:10:43.249 9194-9194/ I/System.out: in runblocking 1 
12-20 16:10:43.253 9194-9194/ I/System.out: after launch 1 

runblocking의 예상되는 행동이 무엇이다? runblocking을 어떻게 사용할 수 있습니까?

답변

0

코드를 차단하더라도 mBinding.tvNoDataFound.text = "test" 작업은 풀 작업자 스레드에서 실행됩니다.

은 주 기능 및 테스트에 사용되는 일시 중단 스타일로 작성된 라이브러리에 정기적 인 차단 코드를 연결하도록 설계되었습니다.

귀하의 경우에는 사용하지 말아야합니다. 백그라운드 작업이 필요한 경우에는 UI 스레드를 차단해서는 안됩니다. 이는 launch 또는 launch(UI)을 사용하는 것과 관계없이 발생합니다. 후자는 모든 것을 동일한 스레드에서 실행하게하고 조인 전에 차단합니다.

그래서 UI 스레드를 차단하고 launch(UI) 또는 View.post {} 표준을 사용하여 나중에 뷰 업데이트를 예약하지 마십시오.

+0

모든 코 루틴이 작업을 완료하는 동안 주 스레드를 차단하는 데 'runBlocking'이 사용되지 않았습니까? runBlocking 실행 순서에 대해 아직도 혼란 스러워요. – vidhi

+0

저에게 이렇게 보입니다. 새로운 coroutine을 실행하고 현재 스레드가 _interruptibly_까지 완료 될 때까지 차단합니다. – tynn