Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/234.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 我刚刚在worker线程上更新了UI,没有问题,我没有';我不知道为什么_Android_Kotlin - Fatal编程技术网

Android 我刚刚在worker线程上更新了UI,没有问题,我没有';我不知道为什么

Android 我刚刚在worker线程上更新了UI,没有问题,我没有';我不知道为什么,android,kotlin,Android,Kotlin,我知道谷歌不推荐在工作线程上更新UI。我试着用Java编写一个演示,结果正如预期的那样崩溃了。然而,当我切换到Kotlin时,我发现,令我惊讶的是,即使我不在UI线程上,我也可以在不崩溃的情况下更新UI。这是怎么发生的 我在Kotlin中的代码: class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(sa

我知道谷歌不推荐在工作线程上更新UI。我试着用Java编写一个演示,结果正如预期的那样崩溃了。然而,当我切换到Kotlin时,我发现,令我惊讶的是,即使我不在UI线程上,我也可以在不崩溃的情况下更新UI。这是怎么发生的

我在Kotlin中的代码:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Thread {
            Thread.sleep(5000)
            myText.text = "updated text"
        }.start()
    }
}
主布局文件仅包含id为“myText”的纯文本视图。 我的android sdk版本是29

我想也许科特林在幕后做了一些线程切换,或者谷歌改变了规则(不太可能),但这只是我的猜测


感谢您的帮助

如果您想用Java更新ui线程。您可以按如下方式继续此逻辑

在UI线程上运行指定的操作。如果当前线程是 UI线程,然后立即执行该操作。如果当前 线程不是UI线程,操作被发布到事件队列 用户界面线程的

对于java

getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        // Do something on UiThread
    }
});
为科特林

runOnUiThread({
    Log.i(TAG, "This is run")
    object : Runnable {                    // This whole expression
        override fun run() {               // returns an object which
            Log.i(TAG, "runOnUiThread")    // is a Runnable, but does
        }                                  // not at any point invoke
    }                                      // its "run" method
    Log.i(TAG, "And so is this")
})

从逻辑上讲,线程与当前主线程相关联,因此,如果您更改线程中的UI元素,那么应该没有问题,而如果您使用handler或runnable创建另一个子线程,那么它将不允许您更改这些线程中的UI元素。您提到的当前线程实际上是主线程,而不是其他线程。
就像coroutine一样,还有DISPATCHER.MAIN,你的代码就是这样的

,如果你创建发布版本并运行此代码,你的应用程序就会崩溃。你能试着在块外和块内打印线程id吗?理想情况下应该有所不同。我试着运行这个代码段,发现它在块内外都将线程id设为1,这意味着线程移位没有发生(不是每次都发生)。你确定它会被更新吗??。我试着运行同样的程序,但什么也没发生。虽然没有发生崩溃,但lambda块中的日志被执行了。我还将所有设置为29。@PrashantJha我尝试使用thread.currentThread().id在线程{}块内外打印线程id,得到了两个不同的id。UI更新确实发生在工作线程中。@RishabhRitweek是的,textview在5秒内在此更新,应用程序没有崩溃。您将update语句放在lambda块中,而textview没有得到更新?weirdI在线程{}块的内部和外部打印了线程ID,并得到了两个不同的ID。我认为这意味着它们运行在不同的线程中?除非您执行thread=new thread,否则ID应该不同如果您访问相同的线程,那么应该获得相同的ids有用信息!但我仍然不明白为什么在Worker线程中更新UI时代码没有崩溃。。。