Reputation: 127
I know that update UI from another thread is forbidden, so I tried that to see what result I will get from the application. Yes, the app will crash when updating the UI component, but there is one case I don't understand, the app run fine.
1)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.textView1);
bt = (Button)findViewById(R.id.button1);
new Thread(){ //1
public void run() {
tv.setText("changed");
}}.start(); //1 }
}
2)
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView)findViewById(R.id.textView1);
bt = (Button)findViewById(R.id.button1);
bt.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View arg0) {
new Thread(){ //1
public void run() {
tv.setText("changed");
}}.start(); //1 }
}
});
}
Sorry for my previous description of my problem, I think most people misunderstand it, so I rephrase the question. There are 2 scenario above, they are supposed to give me crashing error because both create new thread and update the UI component, but in fact, only the second scenario crash but fisrt scenario does not crash. Anyone know the reason?
Upvotes: 0
Views: 1584
Reputation: 3159
Check this exception
E/AndroidRuntime( 7652): FATAL EXCEPTION: Thread-19449
E/AndroidRuntime( 7652): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
E/AndroidRuntime( 7652): at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4357)
E/AndroidRuntime( 7652): at android.view.ViewRootImpl.invalidateChild(ViewRootImpl.java:802)
E/AndroidRuntime( 7652): at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:851)
E/AndroidRuntime( 7652): at android.view.ViewGroup.invalidateChild(ViewGroup.java:4312)
E/AndroidRuntime( 7652): at android.view.View.invalidate(View.java:8603)
E/AndroidRuntime( 7652): at android.view.View.invalidate(View.java:8554)
UI thread checking only be checked in invalidate(rendering) time.
So in create time(onCreate), there is no problem.
You can add Thread.sleep(5000) before setText and the above exception will happen.
Upvotes: 2
Reputation: 1971
Instead of Threading, use asynctask for this kind of operation. It's all described here and very easy to use.
Upvotes: 0
Reputation: 3937
Check this out
private void startthread() {
anihandler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
tv.setText("changed");
}
};
aniThread = new Thread() {
public void run() {
sleep(1000);
anihandler.sendMessage(anihandler
.obtainMessage());
}
};
aniThread.start();
}
Upvotes: 0