Using Handler for a long time method
I am using Handler to make the UI responsive when doing search. I used Handler but why it still displays the error "Only the original thread that created a view hierarchy can touch its views".
@Override
public void onClick(final View view) {
if (view.getId() == R.id.searchButton) {
processThread(searchEditText.getText().toString());
}
}
private void processThread(final String word) {
progressDialog.show();
new Thread() {
@Override
public void run() {
// This is a long time method.
searchWord(word);
searchHandler.sendEmptyMessage(0);
};
}.start();
}
private void searchWord(final String word) {
final String result = dictionaryClient.lookup(word);
resultTextView.setText(result);
}
private final Handler searchHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
};
};
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): android.view.ViewRoot$CalledFromWrongThreadException:
Only the original thread that created a view hierarchy ca开发者_如何学编程n touch its views.
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.ViewRoot.checkThread(ViewRoot.java:2802)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.ViewRoot.requestLayout(ViewRoot.java:594)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.widget.ScrollView.requestLayout(ScrollView.java:1200)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.view.View.requestLayout(View.java:8125)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.widget.TextView.checkForRelayout(TextView.java:5371)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.widget.TextView.setText(TextView.java:2688)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.widget.TextView.setText(TextView.java:2556)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at android.widget.TextView.setText(TextView.java:2531)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at com.megadict.activity.DictionaryActivity.searchWord(DictionaryActivity.java:135)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at com.megadict.activity.DictionaryActivity.access$1(DictionaryActivity.java:133)
07-04 22:04:54.699: ERROR/AndroidRuntime(8815): at com.megadict.activity.DictionaryActivity$2.run(DictionaryActivity.java:146)
Edit: I followed this article .
The problem is this line in searchWord
:
resultTextView.setText(result);
That needs to be executed on the UI thread but is running in the search thread. Replace it with:
searchHandler.post(new Runnable() {
@Override
public void run() {
resultTextView.setText(result);
}
});
the problem with your searchWord method it still updates the UI from another thread,try to keep the code in Handler
private final Handler searchHandler = new Handler() {
@Override
public void handleMessage(final Message msg) {
super.handleMessage(msg);
//call searchWord method from here depends upon your logic
progressDialog.dismiss();
};
};
I answered a similar question to this here.
It's much easier to write AsyncTask classes to replace all your threading/messaging code, and simplify typical "show dialog/do background task/stop dialog" applications.
The code I wrote there could be a direct drop in for your code, replacing the doLogin()
with your searchWord()
.
I would strongly suggest every instance you think of writing a Thread and Handler to replace them with an AsyncTask class.
精彩评论