gpt4 book ai didi

android - 如何在单击按钮时使用运行阻止

转载 作者:太空狗 更新时间:2023-10-29 14:41:15 25 4
gpt4 key购买 nike

运行阻塞的目的是什么?我可以在 OnClickListener 中使用它吗?这里我在 OnClickListener
中使用了 runblocking{}这是我的代码

 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: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.

如果我使用 launch(UI){ } 而不是 launch{ },它会给出如下输出

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:

它不会打印来自另一个协程的“World”。

这是另一个运行阻塞的例子,它使用来自 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

正如我们预期的那样,“after 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

那么运行阻塞的预期行为是什么?如何使用运行阻止?

最佳答案

即使您阻止了代码,mBinding.tvNoDataFound.text = "test" 操作也会在池工作线程上运行。

runBlocking is designed to bridge regular blocking code to libraries that are written in suspending style, to be used in main functions and in tests.

在您的情况下,不应使用它。如果你需要做后台工作,你不应该阻塞 UI 线程。无论使用 launch 还是 launch(UI),都会发生这种情况。后者只是让所有东西都在同一个线程上运行,甚至在连接之前就阻塞了。

所以尽量不要阻塞 UI 线程,稍后通过 launch(UI) 或使用标准 View.post {} 安排 View 更新.

关于android - 如何在单击按钮时使用运行阻止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47904266/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com