I am curious about the safety of this method I have considered using for passing touch events in my Android application (and testing my understanding of concurrency in Java). Here's the basics:
I have a SurfaceView hooked up to SurfaceHolder.Callback to get user input events, mainly the onTouchEvent
callback. After the onTouchEvent
method is invoked, I see if event.getAction() == MotionEvent.ACTION_UP
and, if so, call a method I have named postTouchEvent
which is a member method of my app thread that updates the application's state and draws to the canvas.
SurfaceView
@Override
public boolean onTouchEvent(final MotionEvent event)
{
mAppThread.postTouchEvent(event);
}
AppThread
private volatile MotionEvent mInputEvent;
public void postTouchEvent(final MotionEvent event)
{
this.mInputEvent = event;
}
@Override
public void run()
{
// while loop ...
if (this.mInputEvent != null)
{
final MotionEvent inputEvent = this.mInputEvent;
this.mInputEvent == null;
// update state based on inputEvent (not this.mInputEvent)
}
// draw to canvas
}
Now I understand that it is certainly not atomic, but since I treat it as immutable after receiving it from framework, won't this work? (Instead of synchronizing the post method and the if statement, which I have no problem doing, but I'm asking to learn.)
Here are my thoughts. I know I will have a valid reference to the object but I am unsure in what state I will actually see the object. While testing everything is working out just fine but I am aware of how uncommon threading exceptions can be, even if something is broken.
Also, I can see one problem with this: If another MotionEvent comes though, it's possible that inputEvent in the run()
method will be set to a different event than the one that was referenced when this.mInputEvent != null
was checked, but this really isn't an issue.
So, is there anything I am missing or, for my purposes, should this be ok?