Why doesn't Handler trigger alert as expected?
-
28-09-2019 - |
Question
I need my app to trigger an alert a specified amount of time after a user presses a button. The documentation makes it look like Handler is what I need, and usage appears to be brain dead.
However, I'm finding that despite using postDelayed, my routine is running immediately. I know I'm missing something obvious, but I just can't see it. Why does the code below make the phone vibrate the immediately rather than waiting a minute?
...
final Button button = (Button) findViewById(R.id.btnRun);
final Handler handler = new Handler();
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
...
handler.postDelayed(Vibrate(), 60000);
}
});
...
private Runnable Vibrate() {
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
return null;
}
Solution
That's because you are doing it the wrong way. Just see the flow:
handler.postDelayed(Vibrate(), 60000)
will call the Vibrate()
method immediately, and then it runs the vibrator stuff. In fact Vibrate()
returns null? What do you think that the handler will do with a null reference? You are lucky that it does not throw a NullPointerException
. There are too many examples of how to correctly implement a handler... just dig a little bit more on google.
private class Vibrate implements Runnable{
public void run(){
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
}
}
Then:
handler.postDelayed(new Vibrate(), 60000);
OTHER TIPS
You need to write a run()
method for Vibrate:
private class Vibrate implements Runnable {
public void run(){
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(300);
//return null; don't return anything
}
}
The simplest way for you would be to use anonymous object of Runnable,
...
final Button button = (Button) findViewById(R.id.btnRun); final Handler handler = new Handler();
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
handler.postDelayed(new Runnable() {
public void run() {
v.vibrate(300);
}
}, 60000);
}
});
...