Just testing out a simple block of code in my mainActivity's onCreate:
Timer timer2 = new Timer();
TimerTask testing = new TimerTask() {
public void run() {
Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();
}
};
timer2.schedule(testing, 1000);
I get the "force close" error though.
What gives?
Alright for anyone else who runs into this, I fixed the problem by using a Handler and Runnable to do the Toast, which seems to be needed for UI interaction:
final Handler handler = new Handler();
Timer timer2 = new Timer();
TimerTask testing = new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();
}
});
}
};
timer2.schedule(testing, 1000);
I still don't understand why this is necessary though, perhaps someone could explain? But hey at least this code works lol.
Timer(Tasks) are bad! Do it the Android way: Use a Handler.
As you can see in the code snippet, it’s pretty easy to go that way too:
First we need a Handler that starts the Runnable after 100ms
private Handler handler = new Handler();
handler.postDelayed(runnable, 100);
And we also need the Runnable for the Handler
private Runnable runnable = new Runnable() {
@Override
public void run() {
/* do what you need to do */
foobar();
/* and here comes the "trick" */
handler.postDelayed(this, 100);
}
};
So the “trick” is to tell the handler at the end to start the Runnable again. This way the runnable is started every 100ms, like a scheduleAtFixedRate() TimerTask! If you want it to stop, you can just call handler.removeCallback(runnable) and it won’t start again, until you tell it to
This exact issue is discussed in this article:
http://developer.android.com/resources/articles/timed-ui-updates.html
The app crashes because you are attempting to access elements of the UI thread (a toast) from a different thread (the timer thread). You cannot do this!
You can get round it by either:
Sending a handler message from the timer thread to the UI thread, and then showing the toast in the UI handler function.
OR
In the timer code run use 'runOnUiThread':
@Override
public void run()
{
mainActivity.runOnUiThread(new Runnable() {
public void run() {
// Access/update UI here
Toast.makeText(mainActivity.this, "test", Toast.LENGTH_SHORT).show();
}
});
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With