2017-12-20 25 views
3

ランブロックの目的は何ですか? OnClickListener?で使用できますか? ここで私はこれが私のコードボタンクリックでランブロックを使用する方法

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) 
    } 

である私は打ち上げ(UI){}の代わり打ち上げを使用する場合それはこの

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. 

のようなエラーが表示さOnClickListener
に} {runblocking使用しています{}
、出力は以下のようになります

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: 

別のコルーチンから来た「世界」は印刷されません。

ここで、それは我々が期待したよう上記のコードの

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) 

出力が最後にプリントを "runblocking後"、

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 

である)のonCreate(から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

私にはこういう感じです:新しいコルーチンを実行し、現在のスレッドを_interruptibly_でブロックします。 – tynn

関連する問題