developer.android.com说:
Only objects running on the UI thread have access to other objects on
that thread.
也就是说,以下所有示例(例如A..C)都不应该起作用,因为它们试图修改UI线程中的对象.但实际上案例A和B确实访问了UI线程中的对象(TextView).
这里我们从MainActivity开始一个新线程:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new ClientThread()).start();
}
案例A(UI线程中的对象被修改)
class ClientThread implements Runnable {
public void run() {
final TextView myTextView = (TextView) findViewById(R.id.myTextView);
myTextView.setText("Hello there!");
}
}
情况B(UI线程中的对象被多次修改)
class ClientThread implements Runnable {
public void run() {
final TextView myTextView = (TextView) findViewById(R.id.myTextView);
for (int i=0; i < 600; i++) {
myTextView.setText("Hello there!");
}
}
}
情况C(稍微延迟后,UI线程中的对象未被修改)
class ClientThread implements Runnable {
public void run() {
final TextView myTextView = (TextView) findViewById(R.id.myTextView);
try {Thread.sleep(900);} catch (InterruptedException e) {};
myTextView.setText("Hello there!");
}
}
只有案例C才会抛出异常:
CalledFromWrongThreadException: Only the original thread that created
a view hierarchy can touch its views.
我错过了什么吗?目前看来,在某些情况下,可以从未在UI线程上运行的线程修改UI线程(如果它发生得足够快).
解决方法:
这是一种乐趣.您无法在后台线程中更新UI.但在这种情况下,UI尚未绘制,因此它不会像更新UI那样处理您的代码,而更像是设置值.无论如何,如果您在显示UI后更新它,它将被视为UI更新.
标签:android,multithreading
来源: https://codeday.me/bug/20190708/1401657.html