android-How to solve 'android android.view.ViewRootImpl$CalledFromWrongThreadException
1. The purpose of this post
I would demo how to solve this error when using do some UI operations in a thread:
The code(updateUI from a thread inside an activity or fragment):
public class MyActivity extends AppcompatActivity {
private class CheckThread extends Thread {
@Override
public void run() {
try {
updateUI();
}
catch (Exception ex) {
LogUtils.error("",ex);
}
}
}
public void onCreate(...) {
(new CheckThread()).start();
}
private void updateUI() {
myView.setVisibility(View.VISIBLE);//show some view in a thread
}
}
Run the app, we get this error:
E/MyTest: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:7753)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:1225)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.requestLayout(View.java:23093)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
at android.view.View.requestLayout(View.java:23093)
at android.view.View.setFlags(View.java:14102)
at android.view.View.setVisibility(View.java:9992)
at com.tom.Fragment.showConfirmButton(Fragment.java:87)
at com.tom.Presenter.onGotToken(Presenter.java:188)
at com.tom.Presenter.access$800(Presenter.java:43)
at com.tom.Presenter$CheckThread.run(Presenter.java:168)
2. Environments
- Android Studio 3.x
3. Solution and Code
Because android system do not allow the UI operations to run in the non-UI thread, so you can change the code like this:
public class MyActivity extends AppcompatActivity {
private class CheckThread extends Thread {
@Override
public void run() {
try {
updateUI();
}
catch (Exception ex) {
LogUtils.error("",ex);
}
}
}
public void onCreate(...) {
(new CheckThread()).start();
}
private void updateUI() {
myView.getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
myView.setVisibility(View.VISIBLE);
}
});
}
}
Build and run the app, everything works fine.