gpt4 book ai didi

android - 为什么我在尝试从非 ui 线程更改 UI View 组件时没有得到预期的 CalledFromWrongThreadException

转载 作者:太空狗 更新时间:2023-10-29 13:46:33 24 4
gpt4 key购买 nike

作为 android 编程的初学者,我被教导不能从非 ui 线程更改 UI View 组件,但在下面的简单代码 fragment 中似乎可以完成(非 ui 线程更改按钮文本,这是由 UI 线程创建)...我已经完成研究,我应该得到 CalledFromWrongThreadException。请帮忙?

public class MainActivity extends AppCompatActivity {

Button button;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = findViewById(R.id.button);
}

public void clickDo(View view){
MyRunnable myRunnable = new MyRunnable();
new Thread(myRunnable).start();
}

class MyRunnable implements Runnable{
@Override
public void run() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
button.setText("newText"); //<-------- here?
}
}
}

最佳答案

当您调用 TextView.setText() 时,会发生很多事情。修改正在显示的文本的实际操作是独立于检查 View 布局是否需要更改的操作,更改布局是唯一需要在 UI 上完成的操作线程。

setText()的源代码中,有这么一点点:

if (mLayout != null) {
checkForRelayout();
}

不同于the previously-linked duplicate ,我们知道 mLayout 在这种情况下是非空的。所以我们知道正在调用 checkForRelayout()

但是,查看 checkForRelayout() 表明,在某些情况下,该方法在不调用 requestLayout() 和/或 invalidate()< 的情况下返回。在这些情况下(未调用 requestLayout()),不会抛出预期的 CalledFromWrongThreadException

本质上,如果 TextView 具有固定宽度,并且新文本的行数与旧文本的行数相同,则不会调用 requestLayout()

这意味着您可以从非 UI 线程自由调用 setText() 只要您知道 TextView 具有固定宽度并且新的和旧文本具有相同的行数。


我做了一些实验来验证这一点。事实上,当我的 Button 使用 wrap_content 宽度时,我总是会遇到您的代码崩溃。但是,当我将其更改为 match_parent 时,我只会在新文本换行到第二行时发生崩溃。

关于android - 为什么我在尝试从非 ui 线程更改 UI View 组件时没有得到预期的 CalledFromWrongThreadException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53122802/

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