My app combines a SurfaceView running on its own thread with a bunch of regular Views running on the main application thread. For the most part, this works fine. However, when I try to have something on the SurfaceView's thread trigger a change to one of the UI elements in the main application thread, I get android.View.ViewRoot$CalledFromWrongThreadException.
Is there a right way around this? Should I use an asynctask? Runonuithread()? Or is mixing a SurfaceView on its own thread with other UI elements on the main thread just an inherently bad thing to do?
If my question doesn't make sense, here's pseudocode that may be clearer.
// Activity runs on main application thread
public class MainActivity extends Activity {
RelativeLayout layout;
TextView popup;
MySurfaceView mysurfaceview;
protected void onCreate(Bundle savedInstanceState) {
...
setContentView(layout);
layout.addView(mysurfaceview); // Surface View is displayed
popup.setText("You won"); // created but not displayed yet
}
public void showPopup() {
layout.addView(popup);
}
}
// Surface View runs on its own separate thread
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener {
private ViewThread mThread;
public boolean onTouch(View v, MotionEvent event) {
...
if (someCondition == true) {
mainactivity.showPopup();
// This works because onTouch() is called by main app thread
}
}
public void Draw(Canvas canvas) {
...
if (someCondition == true) {
mainactivity.showPopup();
// This crashes with ViewRoot$CalledFromWrongThreadException
// because Draw is called by mThread
// Is this fixable?
}
}
}