Timer not working in Android when calling invalidate() - android

I want to create a flashing effect by drawing a path with color grey, white (matching to the background), and then grey again. I want to flash 3 times, showing gray for 1 sec, white for 1 sec gray again for 1 sec, etc.
When I created a Handler for postDelayed(), the program skipped over the run() and did not execute it in the timing set, and no flashing occurred:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
invalidate(); //calls onDraw()
Log.d(TAG, "Flashing now now");
}
}, 1000);
How would I implement such a flashing functionality with a timer and flash it 3 times?
Thanks!

You can try something like this,
int delay = 5000; // delay for 5 sec.
int period = 1000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("done}
}, delay, period);
Otherwise you have plenty other examples to follow like this Example 1, Example 2, Example 3 etc. Let me know if you still need help.

This is a working code example of how we flash a globe from blue to red and back again. You can modify the code on the inside to limit how many times and what time delay you want.
protected MyGlobeFlasherHandler handlerFlashGlobe = new MyGlobeFlasherHandler(this);
#Override
protected onCreate(Bundle bundle) {
handlerFlashGlobe.sendEmptyMessageDelayed(0, 700);
}
/**
* private static handler so there are no leaked activities.
*/
protected static class MyGlobeFlasherHandler extends Handler {
private final WeakReference<HomeBase> activity;
public MyGlobeFlasherHandler(HomeBase activity) {
this.activity = new WeakReference<HomeBase>(activity);
}
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (activity.get() != null) {
if (activity.get().shadedGlobe) {
activity.get().imgData.setImageDrawable(activity.get().getResources().getDrawable(R.drawable.globe_blue));
} else {
activity.get().imgData.setImageDrawable(activity.get().getResources().getDrawable(R.drawable.globe_red));
}
activity.get().shadedGlobe = !activity.get().shadedGlobe;
sendEmptyMessageDelayed(0, 700);
}
}
}

Related

How can I control a timer in android?

I want to make an application about mini game.
Detail : In 2 seconds you must to answer a question if you don't answer or the answer is wrong -> Game Over . But if your answer is true the Timer will reset become 0 and countdown again with diffirent question.
I have already seen many code about timer in website but I don't understand clearly about it :(
So I want to ask : How can i set up a timer run only 2 seconds and how can i reset it and continue with a new question ?
Please help me.
you can use CountDownTimer in android like this:
public class Myclass {
myTimer timer =new myTimer(2000,1000);
public void creatQuestion(){
timer.start();
//method you init question and show it to user
}
public void getUserAnswer(/*evry thing you expected*/)
{
//if answer is true call timer.start()
//else call timer.onFinish(); to run onfinish in timer
}
public class myTimer extends CountDownTimer {
public myTimer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onTick(long millisUntilFinished) {
// you can update ui here
}
#Override
public void onFinish() {
this.cancel();
//fire game over event
}
}
}
i hope it make you satisfy
I've done something similar using Thread/Runnable.
Thread t = new Thread(new Runnable() {
public void run() {
final long startTime = getTime();
final long maxEndTime = startTime + 2000L;
try {
while (shouldContinueWaiting()) {
if (getTime() > maxEndTime) {
throw new TimeoutException();
}
sleep();
}
} catch (InterruptedException e) {
handleInterrupt();
} catch (TimeoutException e) {
handleTimeout();
}
}
boolean shouldContinueWaiting() {
// Has the user already answered?
}
void handleInterrupt() {
// The user has answered. Dispose of this thread.
}
void handleTimeout() {
// User didn't answer in time
}
void sleep() throws InterruptedException {
Thread.sleep(SLEEP_DURATION_IN_MILLIS);
}
void getTime() {
return System.currentTimeMillis();
}
then you can start/restart the thread by:
t = new Thread(same as above...);
t.start();
and stop by:
t.interrupt();
We want to use the Timer class.
private Timer timer;
When you're ready for the timer to start counting -- let's say it's after you press a certain button -- do this to start it:
timer = new Timer();
timer.scheduleAtFixedRate(incrementTime(), 0, 100);
The first line is us creating a new Timer. Pretty standard. The second line, however, is the one I wanted you to see.
incrementTime() is a method that is called at the end of every "tick" of the clock. This method can be called whatever you want, but it has to return an instance of TimerTask. You could even make an anonymous interface if you want, but I prefer moving it off into its own section of code.
The 0 is our starting location. We start counting from here. Simple.
The 100 is how large a "tick" of the clock is (in milliseconds). Here, it's every 100 milliseconds, or every 1/10 of a second. I used this value at the time of writing this code because I was making a stopwatch application and I wanted my clock to change every 0.1 seconds.
As for your project, I'd suggest making the timer's task be your question switch method. Make it happen every 2000 milliseconds, or 2 seconds.
You can use a Handler.
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
//this will happen after 2000 ms
}
}, 2000);
Maybe this can help you:
Handler handler = new Handler();
handler.post(new Runnable() {
#Override
public void run() {
// FIRE GAME OVER
handler.postDelayed(this, 2000); // set time here to refresh textView
}
});
You can fire your game over after 2000 milliseconds.
If you get the question correct -> remove callback from handler and reset it when the next question starts.

Android. How to stop a handler once it executed a runnable once

EDIT: Code works now. I ended up calling loadingIllusionLoader() from within createDialog()...
I am trying to get a 'fake' progress bar to show up once a user presses a button. I want the progress bar to appear for some random time ~ 2000ms and then have a Dialog box appear as well as hiding the progress bar (because it 'loaded').
I was told to try and use handler since Thread.sleep locks up the UI, which I dont want to really do. However, once I execute the code below, it runs the handler's postDelayed function and a new Dialog box appears every moment or so... the handeler is executing itself over and over again. How do I STOP the handler. the removeCallbacksAndMessages function on the handler was an option, but Im not sure how to exactly STOP the Dialog boxes from opening.
public void loadingIllusionLoader()
{
ProgressBar theCircleLoader = (ProgressBar) findViewById(R.id.progressBar2);
theCircleLoader.setVisibility(View.VISIBLE);
int timeToRest = (int) (Math.random() * 1000) + 1500;
final Handler newHandle = new Handler();
newHandle.postDelayed(new Runnable() {
#Override
public void run() {
createDialog();
hidingIllusionLoader();
newHandle.removeCallbacksAndMessages(null);
}
}, timeToRest);
}
public void hidingIllusionLoader()
{
ProgressBar theCircleLoader = (ProgressBar) findViewById(R.id.progressBar2);
theCircleLoader.setVisibility(View.INVISIBLE);
}
I think you'd rather want to use a CountDownTimer:
CountDownTimer timer = new CountDownTimer( 10000, 1000 ) {
#Override public void onTick( long millisUntilFinished ) {
theCircleLoader.setProgress( theCircleLoader.getProgress() - 1 );
}
#Override public void onFinish() {
theCircleLoader.setVisibility(View.INVISIBLE);
}
};
EDIT: almost forgotten:
timer.start();
EDIT2:
after looking at your code, I suggest you modify it so:
Random rnd = new Random();
int progressBarMax = rnd.nextInt( 10 ) + 1; // 10 - change it the way you like
int timeToRest = progressBarMax * 500;
theBarLoader.setMax( progressBarMax );
theBarLoader.setProgress( 0 );
CountDownTimer theTimer = new CountDownTimer(timeToRest, 500)
{
#Override public void onTick( long millisUntilFinished ) {
theBarLoader.setProgress( theCircleLoader.getProgress() + 1 );
}
#Override public void onFinish() {
theCircleLoader.setVisibility(View.INVISIBLE);
// theBarLoader.setVisibility(View.INVISIBLE);
createDialog();
}
};
theTimer.start();

Get new value in edit box after N seconds without button in android

I am new in android and so, I need your help.
I want new and refreshed values in edit box such that after every 10 seconds without button click it brings changed value of PLC on edit box in my android device.
try this,
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
edittext.settext(yourtext);
}
}, 10000);
You can do this with a Timer for example. But think abaout, that this what You want to do is a Little bit battery intensive :
//create a Timer and TimerTask
private Timer timer;
private YourTimerTask yourTimerTask;
private void activateTimer(){
if(timer!=null){
timer.cancel();
}
timer = new Timer();
yourTimerTask = new YourTimerTask();
//this timer starts after 1 second and repeats every 10 seconds
timer.schedule(yourTimerTask, 1000, 10000);
}
private class YourTimerTask extends TimerTask {
#Override
public void run() {
runOnUiThread(new Runnable(){
#Override
public void run() {
yourEditBox.setText(yourText);
}});
}
}
I think with Edit box You mean an EditText? Anyway, this example is not tested, just from scratch. But it should give You an idea how to do.

How to periodically display a rectangle in an android activity

I would like to display a white rectangle periodically on the android screen; or change the background color. For example, every 500ms I want the screen color to change from black to white, for around 200ms, then back to black.
What is the best way to do this? I did try with an asynctask, but got an error that only the original thread can touch the View. I have a similar asynctask which sounds a periodic tone and that works fine.
SOLUTION:
With help from the responders I resolved my issue by creating two timers one for black and one for white. The black one starts delayed by the duration that I want to display the white screen. Both have the same execution rate, thus the white screen is displayed then, after duration ms the black screen is displayed. For example, the screen is black but flashes white every second for 200 ms.
#Override
protected void onResume() {
super.onResume();
mBlackTimer = new Timer();
mBlackTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setBackgroundColor(Color.parseColor("#000000"));
}
});
}
}, duration, (long) (1000 / visionPeriod));
mWhiteTimer = new Timer();
mWhiteTimer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
view.setBackgroundColor(Color.parseColor("#ffffff"));
}
});
}
}, 0, (long) (1000 / visionPeriod));
}
You can use timer class for this to perform some task on repeated interval:
//Declare the timer
Timer t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
//Called each time when 1000 milliseconds (1 second) (the period parameter)
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
0,
//Set the amount of time between each execution (in milliseconds)
1000);
AsyncTask is mainly used to perform background thread activity like downloading data from remote server. It runs on it's own thread that's why when from the AsyncTask you try to access any View of your Activity it gives that Error that only the original thread can touch the View.
You may use Timer class or AlarmManager class for repetitive tasks. Visit my previous answer.
Create a Timer task method and inside the timertask and give it a periodic duration of 700ms show the black background and then create a handler for showing white background and post delay it for 500ms
try all of this in the uithread only
don't use new thread or asynctask
like this:
mTimer = new Timer();
mTtask = new TimerTask() {
public void run() {
//set your black background here
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// set your white background here
}
}, 500);
}
};
mTimer.schedule(mTtask, 1, 700);

Updating UI on button click after a certain time

I have a TextView. I want to update its text (append a "1") after 1 second of a button click.
public class HaikuDisplay extends Activity {
Method m;
Timer t;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t = new Timer();
m = HaikuDisplay.class.getMethod("change");
}
//Event handler of the button
public void onRefresh(View view)
{
//To have the reference of this inside the TimerTask
final HaikuDisplay hd = this;
TimerTask task1 = new TimerTask(){
public void run(){
/*
* I tried to update the text here but since this is not the UI thread, it does not allow to do so.
*/
//Calls change() method
m.invoke(hd, (Object[])null);
}
};
t.schedule(task1, 1000);
}
public void change()
{
//Appends a "1" to the TextView
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "1");
}
//Event handler of another button which updates the text directly by appending "2".
//This works fine unless I click the first button.
public void onRefresh1(View view)
{
TextView t = (TextView)findViewById(R.id.textView1);
t.setText(t.getText() + "2");
}
}
Consider all Exceptions be handled.
On first click, m.invoke gives InvocationTargetException. But it calls the method change() on successive invokes without any Exceptions(verified by logging). But it does not update the text. Where am I wrong?
Also, I see in the debugger that it creates a new Thread every time I click the button. That is fine. But why isn't it removing the previous Threads though their execution has been completed?
Do something like this
public void onRefresh1(View v) {
// You can have this in a field not to find it every time
final EditText t = (EditText) findViewById(R.id.textView1);
t.postDelayed(new Runnable() {
#Override
public void run() {
t.append("1");
}
}, 1000);
}
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// Update UI
}
}, 1000);
implement this on button click
UPDATE:
There are some other answers. dtmilano suggested another solution which is almost same to mine except he is calling the postDelayed method of View class and In my answer I used postDelayed method of handler class.
from the api reference of android the postDelayed method of Handler says
The runnable will be run on the thread to which this handler is
attached.
and the postDelayed method of View says
The runnable will be run on the user interface thread.
This is the only difference between these two solution. in my answer instead of creating new Handler every time you can use any other handler instance. Then the runnable will be run on that thread where that specific handler is declared. And if the postDelayed of EditText is used the the runnable method will be run on the user Interface Thread.
Now the performance issue, both has the same performance (If anybody can prove me wrong with reference I will be happy)
That's looking awful convoluted - have you considered using CountDownTimer instead?
new CountDownTimer(1000, 1000) {
public void onTick(long millisUntilFinished) {
// no-op
}
public void onFinish() {
change();
}
}.start();
This should call change (and hence change the text) on the UI thread, avoiding reflection and threading errors.
Hi Use the following code for that. Hope this will help you .
new java.util.Timer().schedule(
new java.util.TimerTask() {
#Override
public void run() {
// your code here
}
},
1000
);
Have a look of this question also.
display data after every 10 seconds in Android
You can try with this also.
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
public void run() {
doStuff();
/*
* Now register it for running next time
*/
handler.postDelayed(this, 1000);
}
};
**EDIT 3**
Try with this once you are need to enable once (i mean if you put your code in yourmethod()== this will get automatically call 1 seconds once.
private Timer timer;
TimerTask refresher;
// Initialization code in onCreate or similar:
timer = new Timer();
refresher = new TimerTask() {
public void run() {
yourmethod();
};
};
// first event immediately, following after 1 seconds each
timer.scheduleAtFixedRate(refresher, 0,100);

Categories

Resources