Im using a Timer to continuously update a TextView, but I'm having trouble restarting the timer during the onResume() method. I use timer.cancel() in the onPause() and onDestroy() methods, but how do I restart the timer in onResume()?
This is my timer code...
int delay = 1000;
int period = 1000;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
//I update the TextView here
}
}, delay, period);
An easier alternative is to use the Handler class. I wouldn't recommend the Timer class because it has no bearing on the life cycle of your Activity and you will have to worry about any potential threading problems yourself. The beauty of using the Handler is that all your callbacks will be on the main thread (so no threading issues to worry about). The following is a simple example on how to do this.
#Override
protected void onCreate(Bundle savedInstanceState)
{
....
mHandler = new Handler();
}
#Override
protected void onResume()
{
mHandler.postDelayed(myRunnable, UPDATE_RATE);
}
#Override
protected void onPause()
{
mHandler.removeCallbacks(myRunnable);
}
private final Runnable myRunnable= new Runnable() {
#Override
public void run()
{
//Do task
mHandler.postDelayed(myRunnable, UPDATE_RATE);
}
}
You dont restart the timer. Instead use a new timer i.e inside onResume() create a new timer. As you are no longer using the previous one, garbage collection will take care of it. So in onResume() use the following code:
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
//update the TextView here
}
}, delay, period);
Related
I have implemented a simple timer with CountDownTimer on my game and I need it to start ater a few seconds when the activity is started.
On my main activity's onCreate method, I call this:
playingTime();
Which is as follow
public void playingTime() {
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
String elapsedTime = String.valueOf(millisUntilFinished / 1000);
timer.setText(elapsedTime);
}
public void onFinish() {
timer.setText(R.string.timer_game_over_text);
}
}.start();
}
The timer start normally but immediatelly as the activity is launched. I would like to set a delay before it get executed or if there is a better way to set timer in games. (Count down timer and nomal timer)
You can use the handler in onCreate() method as shown below and playingTime will be called after 1 second
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
playingTime();
}
}, 1000);
You can add delay using Handler like as below:
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//Executed after YOUR_DELAY_IN_MILLIS
playingTime()
}
}, YOUR_DELAY_IN_MILLIS);
Put the code in your activity onCreate() method
You can set a delay like this :
new Handler().postDelayed(new Runnable(){
#Override
public void run() {
// call method here
}
}, MY_DELAY_IN_MS);
Replace MY_DELAY_IN_MS with your own delay
Here is my fixed rate timer code. Can i pause this timer while activity goes in onPause(); . If so then what would you suggest me put in onPause(); method and timer should start work as app comes to onResume();:
//Declare the timer
t = new Timer();
//Set the schedule function and rate
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// code here
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
20000,
//Set the amount of time between each execution (in milliseconds)
40000);
You can use Timer.cancel()
Terminates this timer, discarding any currently scheduled tasks. Does not interfere with a currently executing task (if it exists). Once a timer has been terminated, its execution thread terminates gracefully, and no more tasks may be scheduled on it.
Declare the timer as global
t = new Timer();
Try this
#Override
protected void onPause() {
super.onPause();
t.cancel();
}
timer should start work as app comes to onResume();:
You need to start Timer in onResume()
Try this
#Override
protected void onResume() {
super.onResume();
t.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// code here
}
},
//Set how long before to start calling the TimerTask (in milliseconds)
20000,
//Set the amount of time between each execution (in milliseconds)
40000);
}
I am using java and android studio. I am trying to close an activity I set up with a scheduleatfixedrate when I pause or destroy the app. The problem is I cannot get the code to resolve the timer and tasknew reference I use to set up the scheduleatrfixedrate in the onpause and onDestroy methods. Below is my code:
#Override
protected void onResume() {
super.onResume();
TimerTask tasknew = new readDevice();
Timer timer = new Timer();
timer.scheduleAtFixedRate(tasknew, 1000, 500);
}
// Activity paused
#Override
protected void onPause() {
super.onPause();
tasknew.cancel();
timer.purge();
}
Without being able to cancel the timer, it just keeps running in the background.
Update:
I solved the problem which I update my solution in case someone else new to java has this problem. I found out all I had to do is move the statement creating tasknew and timer outside of onResume and moved the cancel and purge to the onDestroy method. Below is my working code.
public class DeviceControlActivity extends Activity {
private TimerTask tasknew = new readDevice();
private Timer timer = new Timer();
#Override
protected void onResume() {
super.onResume();
timer.scheduleAtFixedRate(tasknew, 1000, 500);
}
#Override
protected void onDestroy() {
super.onDestroy();
tasknew.cancel();
timer.purge();
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
}
I guess it would have been enough to create a daemon Timer:
new Timer(true)
So, the timer would end when the rest of non-daemon threads of the program end.
I am trying to get a timer to run in a separate thread.
I have the following declaration before my onCreate function:
TimerTask scanTask;
Timer t = new Timer();
Then the following code within onCreate:
Runnable runnable = new Runnable() {
#Override
public void run() {
scanTask = new TimerTask() {
#Override
public void run() {
System.out.println("timer test");
}
};
t.schedule(scanTask, 0, 5000);
CountDownTimer waitTimer;
waitTimer = new CountDownTimer(20000,300) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
t.cancel();
System.out.println("Timer stopped");
}
}.start();
}
};
Thread periodic_scan = new Thread(runnable);
periodic_scan.start();
However, when I run the app, it crashes and gives me the error:
java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
I'm not sure I completely understand why this error is occurring. Is it something to do with the UI thread? Also, I'm not sure whether the way I've tried to implement this is correct. This is my first time trying to deal with threads in Android.
you can use HandlerThread like
HandlerThread handlerThread = new HandlerThread("name");
handlerThread.start();
Handler threadHandler = new Handler(handlerThread.getLooper(),new Callback() {
public boolean handleMessage(Message msg) {
return true;
}
});
I ended up changing the code a bit and decided to use a Thread class:
class TimerThread extends Thread {
TimerTask scanTask;
Timer t = new Timer();
#Override
public void run() {
Looper.prepare();
scanTask = new TimerTask() {
public void run() {
System.out.println("timer test");
}
};
t.schedule(scanTask, 0, 5000);
CountDownTimer waitTimer;
waitTimer = new CountDownTimer(20000,300) {
#Override
public void onTick(long l) {
}
#Override
public void onFinish() {
t.cancel();
System.out.println("Timer stopped");
}
}.start();
Looper.loop();
}
}
In onCreate I used the following:
new TimerThread().start();
The program now works without any errors, however the only problem now is that there is a noticeable 2-3 second lag when the program loads up before the UI renders to the screen.
I'm not sure why this is happening if the timer function I am using is running on a separate thread, unless I've missed something here...
If you create a handler (or any class you call creates a handler) it needs to be in a Thread that has a Looper on it, and has called Looper.prepare(). Either TimerTask or CountDownTimer is doing that. How to fix it depends on where you want the events to be posted to. If you want them on the UI thread, you'll have to create the handler on the UI thread. If you want them on this thread, then you need to call Looper.prepare and Looper.loop at some point.
The UI thread already has a looper (the framework starts it for you) so its always ok to make handlers there.
I want to cyclically update an Android Layout. For this purpose I wrote a short class derived from TimerTask.
Unfortunately my code causes an exception and I do not really know, what the problem might be. :(
So maybe anybody could help.
Thanks
Chris
Here's my code:
In the main activity I've got:
private MyLayoutClass m_MyLayout;
...
public void onCreate(Bundle savedInstanceState)
{
...
m_MyLayout = new AdLayout(this);
Timer caretaker = new Timer();
caretaker.schedule(new MyReloadTimerTask(m_MyLayout), 1000, 5000);
...
}
This is my derived TimerTask class:
public class MyReloadTimerTask extends TimerTask
{
private MyLayoutClass m_MyLayout;
public MyReloadTimerTask(MyLayoutClass aLayout)
{
m_MyLayout = aLayout;
}
#Override
public void run()
{
m_MyLayout.doReload();
}
}
The doReload() cannot be executed, I get an exception with this message: Can't create handler inside thread that has not called Looper.prepare()
Timertask runs on a different thread. So you cannot not update/access ui from a background thread.
Probably m_MyLayout.doReload() is updating ui. Use a Handler or runOnUiThread
runOnUiThread(new Runnable() {
#Override
public void run() {
m_MyLayout.doReload()
}
});
Using Handler
Handler m_handler;
Runnable m_handlerTask ;
m_handler = new Handler();
m_handlerTask = new Runnable()
{
#Override
public void run() {
// do something
m_handler.postDelayed(m_handlerTask, 1000);
// repeat some task every 1 second
}
};
m_handlerTask.run();
To cancel the run
m_handler.removeCallbacks(m_handlerTask);