问题
Consider the following code:
new Thread() {
@Override
public void run() {
myTextView.setText("Some text");
}
}.start();
On pre-Lollipop androids, that code causes the CalledFromWrongThreadException
exception, but why does it work fine on Lollipop androids?
Testing environment: Genymotion emulator running Android 5.1
The code was inside the onCreateView()
method of the Fragment
class.
回答1:
It's a matter of timing, for example inserting your code in onCreate() would not crash the app on Samsung Galaxy S3 nor Nexus 7 2013 on Android 5.1. However, if you modify the code such that it's constantly updating the TextView:
new Thread() {
@Override
public void run() {
int count = 0;
while (true) {
SystemClock.sleep(16);
((TextView) findViewById(R.id.test)).setText(count++ + "");
}
}
}.start();
Then it'll crash on ~18th call, when TextView.setText(String)
inadvertently calls View.requestLayout();
which eventually calls ViewRootImpl.requestLayout()
that actually does check for correct thread.
This is probably done to reduce the overhead of thread checking to a minimum.
回答2:
What I have noticed so far, If you create a new thread in an Activity, the code compiles and runs without and error.
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread() {
@Override
public void run() {
txtName.setText("Some text");
}
}.start();
}
but if you create a new thread in a service or asynctask, it causes the CalledFromWrongThreadException exception.
来源:https://stackoverflow.com/questions/29990029/why-is-it-possible-on-android-5-lollipop-to-directly-change-ui-views-from-othe