I recently restarted developing on Android, after (too many) years. I had to catch up with all the updates in the framework, as I was using Android 1.6/2.0 at the time, but all in all, I found out it was easier than I thought.
I decided to create a small game-like app to get back in shape before engaging all the new things in Android 4.
And I found I needed to sleep() for a bit after a user action.
The problem
In my app/game, when users select a button, they get a feedback and, after 2 seconds, something else happens.
My first try was this:
public void onButtonClicked(View view)
{
Button btn = (Button)findViewById(R.id.my_button);
btn.setText("Got it!");
saveWhateverTheUserDid();
SystemClock.sleep(1000);
btn.setText("Click me!");
}
Plain, linear, wrong.
Turns out that the main thread, as every manual says, is really the only thread dealing with the interface. What does it mean? It means that until the callback returns, the interface does NOT get updated, and your application will not receive any other signal (but they will queue!). Everything is frozen.
So i started to look for...
The solution
The solution is to spawn a thread that, after 1000 ms, will spawn another thread, which will run an instruction on the UI thread.
Confused? Me too...
This is the code:
public void onButtonClicked(View view)
{
Button btn = (Button)findViewById(R.id.my_button);
btn.setText("Got it!");
saveWhateverTheUserDid();
Timer myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
runOnUiThread(new Runnable() {
public void run() {
btn.setText("Click me!");
}
});
}
}, 1000);
}
Not the cleanest code I have ever seen, but it does its job. Naturally, you can extract the inner anonymous class and create a “proper” one, but in this case I had no need for code reuse or generalization.
For reference, this would have been the Javascript (with a little help from jQuery) equivalent:
function onButtonClicked(evt)
{
var btn = $('button.my_button');
btn.text('Got it!');
saveWhateverTheUserDid();
setTimeout(function() {
btn.text('Click me!');
}, 1000);
}
</code>
Java verbosity strikes again! :)
But Java is not my main area of expertise. Am I missing something?