Android 为什么我能够从后台线程操作UI元素?
但若我为线程添加延迟,它就不起作用了。所以我可以从非UI线程操作UI元素。有人能为我澄清一下这个情况吗?Android 为什么我能够从后台线程操作UI元素?,android,Android,但若我为线程添加延迟,它就不起作用了。所以我可以从非UI线程操作UI元素。有人能为我澄清一下这个情况吗? }否,如果要操作UI元素,必须从主线程执行。否,如果要操作UI元素,必须从主线程执行。Android实际上不会阻止您从主线程外部更新UI。这更像是一颗滴答作响的定时炸弹。如果主UI线程当时没有更新UI,那么您的线程可以进行更新。在SurfaceView之外,根本无法控制它何时发生 至少这是我的理解。我不是100%确定,但我以前能够(意外地)从主UI线程外部更新UI。有时它会工作,有时不会,所
}否,如果要操作UI元素,必须从主线程执行。否,如果要操作UI元素,必须从主线程执行。Android实际上不会阻止您从主线程外部更新UI。这更像是一颗滴答作响的定时炸弹。如果主UI线程当时没有更新UI,那么您的线程可以进行更新。在
SurfaceView
之外,根本无法控制它何时发生
至少这是我的理解。我不是100%确定,但我以前能够(意外地)从主UI线程外部更新UI。有时它会工作,有时不会,所以我认为这是某种形式的ConcurrentModificationException。Android实际上不会阻止您从主线程之外更新UI。这更像是一颗滴答作响的定时炸弹。如果主UI线程当时没有更新UI,那么您的线程可以进行更新。在
SurfaceView
之外,根本无法控制它何时发生
至少这是我的理解。我不是100%确定,但我以前能够(意外地)从主UI线程外部更新UI。有时有效,有时无效,所以我认为这是某种形式的ConcurrentModificationException。我不确定问题是什么。他想知道为什么在[非主]线程中设置TextViews文本时不会崩溃。你说得对。为什么上面的代码在我不从UI线程设置TextView文本的情况下工作?当您按原样运行此代码时,TextView中的文本是否会更改?是的。!?但是线程。睡眠(1*1000);mTextView.setText(“as”);现在它不起作用了。我不确定问题是什么。他想知道为什么在[非主]线程中设置文本视图文本时不崩溃。你是对的。为什么上面的代码在我不从UI线程设置TextView文本的情况下工作?当您按原样运行此代码时,TextView中的文本是否会更改?是的。!?但是线程。睡眠(1*1000);mTextView.setText(“as”);现在它不起作用了,但上面的代码起作用了。我不能从UI线程更改TextView的文本。但上面的代码可以工作。我无法从UI线程更改TextView的文本。我不知道这会起作用。据我所知,这是一条硬性规定。谢谢你的信息。尽管我仍然强烈建议OP不要选择从不同的线程对UI进行更改,即使它在测试期间对您有效。它可能会在不同的设备上失败,或者在不同的情况下失败。在以后的操作系统版本中可能会很快失败,但我确实知道我以前做过,这是一个非常难找到原因的错误,就像我说的,它只会偶尔崩溃。你有没有尝试过用循环来围绕这个问题,直到它找到更新UI的机会(这将证明这一点)?我想这是可行的。不过,我不知道为什么睡眠会有什么不同。它似乎也只会偶尔崩溃。除非是竞争条件,睡眠允许Android在返回新线程之前切换到主UI线程。@Tim:尝试用永久循环替换睡眠,并发送通知ter到Logcat查看在UI崩溃之前更新了多少次。我不知道这会起作用。据我所知,这是一个艰难而快速的过程(强制执行)规则。感谢您提供的信息。尽管我仍然强烈建议OP不要选择从不同线程对UI进行更改,即使它在测试期间对您有效。它可能会在不同的设备上失败,或者在不同的情况下失败。在以后的OS版本中,这可能是一个快速失败,但我确实知道我以前做过,这是一个错误n如我所说,很难找到原因,它只是有时会崩溃。你有没有尝试过用循环来围绕睡眠这个问题,直到它找到更新UI的机会(这将证明这一点)?我想这是可行的。不过,我不知道为什么睡眠会有什么不同。它似乎也只会偶尔崩溃。除非是竞争条件,睡眠允许Android在返回新线程之前切换到主UI线程。@Tim:尝试用永久循环替换睡眠,并发送通知请转到Logcat,查看在UI崩溃之前更新了多少次。
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mTextView = (TextView) findViewById(R.id.text);
new Thread(new Runnable() {
@Override
public void run() {
mTextView.setText("Hello");
}
}).start();