Updating UI items from multiple threads

So I recently found out that only one thread is ever allowed to update things like ImageViews and whatnot. If you try to make another thread update them, everything breaks, and all of a sudden, that ImageView never ever updates again. This was causing trouble in RemoteDroid because I wanted the tap to click to update the on-screen button state, but the tap events had to come from a Timer object, which put everything in a different thread.

Anyway, if you need to make a graphical change from another thread, the solution is to use the Handler class. The you use it is by creating a handler in your UI thread, then create some Runnable objects that call all your graphics methods. Here’s an example:

public class Thing extends Activity {
        private Handler = new Handler();
        // runnables for updating state
        private runnable buttonOn = new Runnable() {
                private void run() {
                        drawImageOn();
                }
        };
        private runnable buttonOff = new Runnable() {
                private void run() {
                        drawImageOff();
                }
        };
        // our ImageView
        private ImageView iv;
        // a Timer object, which creates another thread for doing something else
        private Timer timer = new Timer();

        public void onCreate(Bundle savedInstanceState) {
                // set ref to ImageView
                this.iv = (ImageView)this.findViewById(R.id.whatever);
                //
                this.handler.post(this.buttonOn);
                // Let's start up another thread for whatever reason
                this.timer.scheduleAtFixedRate(new TimerTask() {
                        public void run() {
                                // If we tried to call drawImageOff() here directly, something would break.
                                handler.post(buttonOff);
                        }
                }, 0, 500);
        }

        // drawing methods

        public void drawImageOn() {
                // draw in our ImageView here
                ...
        }

        public void drawImageOff() {
                // draw in our ImageView here
                ...
        }
}

So basically, you’re setting up a few Runnables for changing graphical state, and then making every thread use the Handler for changing between those states.

Comments are closed.

Related Links

Resource Links