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);
}
Related
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.
In my onCreate method in my activity i call a method from an object and pass the methods value as 1 which means to start a timer in the objects class. However I want to stop the timer whenever the app closes, loses focus or someone pressed the back button on their device and exited the app. I tried doing this below my onCreate method with an onPause, onStop, onDestroy and entered the methods value as 2 for the object which means to cancel the timer. However my problem is that whenever someone presses the back button on their device and then goes back in to the app the same timer is running twice because the app did not cancel the timer in the onStop, onPause or onDestroy. Why didn't the onStop, onPause and onDestroy stop the timer and how do i make it stop the timer so two arent running when the app is reopened?
Activity below
Ship mShip = new Ship(0,0,0);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
mShip.timerStart(1);
}
#Override
public void onPause()
{
super.onPause();
mShip.timerStart(2);
}
#Override
public void onStop()
{
super.onStop();
mShip.timerStart(2);
}
#Override
public void onDestroy()
{
super.onDestroy();
mShip.timerStart(2);
}
Ship Class below
public static int counter = 0;
public static int counterPerSec = 5;
TimerClass startTimer = (TimerClass) new TimerClass(2000,1000)
{
#Override
public void onFinish() {
counter += counterPerSec;
this.start();
}
};
public void timerStart(int x) {
if(x == 1)
{
startTimer.start();
}
if(x == 2)
{
startTimer.cancel();
}
}
Timer Class
public class TimerClass extends CountDownTimer {
public TimerClass(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override // when timer is finished
public void onFinish() {
this.start();
}
#Override // on every tick of the timer
public void onTick(long millisUntilFinished) {
}
}
I can not see, why your timer is not canceled. But there is another bug in your code: You can not pause and resume a countdown timer by calling resume and start.
If your time gets canceled, you should save the old timer vaules. And if your timer has to be resumed, you can create a new timer with the old timer values. See: Android: How to pause and resume a Count Down Timer?
To your question: Can you debug and check if onPause, onStop, onDestroy is called? Is there any exception thrown? Do you have any compile warnings?
Last important question: How do you know that two timers are running?
Well, I think I can correctly assume that onPause, onStop, and onDestroy are executing, so I would venture to guess that there is a bug in your TimerClass class.
I'm trying to execute some function repeatedly for every 5 sec & it's working fine.
I wanted this timer to stop when the app is closed or back button is pressed.
int delay = 0;
int period = 5000; // repeat every sec.
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
System.out.println("done");
}
}, delay, period);
}
Don't use a Timer just use a Handler
private boolean keepLooping = true;
private static final int DELAY = 1000 * 5;
final Handler printHandler = new Handler();
Runnable printStuff = new Runnable(){
#Override
public void run(){
System.out.println("done");
if(keepLooping)
printHandler.postDelayed(this, DELAY);
}
}
//wherever you want to start your printing
printHandler.postDelayed(printStuff, DELAY);
keepLooping = true;
//when back is pressed or app is stopped
keepLooping = false;
printHandler.removeCallbacks(printStuff);
postDelayed will run the runnable on the delay you want. If you want it to loop forever just start the handler again from within the runnable. When you want it to stop just removeCallbacks which will prevent the looping.
In Android you can override below methods to identify the back press and activity close, then you can have the code to cancel the timer.
1. onDestroy()
2. onBackPressed()
In method implementation you can use below statements to stop.
timer.cancel();
timer.purge();
ex:
#Override
public void onBackPressed() {
timer.cancel();
timer.purge();
super.onBackPressed();
}
I guess this would help..
I'm trying to make a countdown timer in android for use in a small android app. The app will countdown from some number of seconds to 0, upon which it will do some action. I'm using the coundowntimer supplied by android.os.countdowntimer. Here is my code:
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.quizlayout);
new CountDownTimer(30000, 1000) {
TextView tx = (TextView) findViewById(R.id.textView2);
public void onTick(long millisUntilFinished) {
tx.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
tx.setText("done!");
}
}.start();
}
However, this countdown timer is really slow. It takes like 3 real-time seconds for the timer to countdown by one second. I wonder what's going on? The code I have above is more or less copied straight from google (CountDownTimer)
Can anyone help me as per why my timer is so slow, and offer a way to speed it up a bit?
(EDIT): I am running this on an emulator, the intel atom x86. I am emulating an android 2.3.3 environment.
According to Android documentation for countdown timer
The calls to onTick(long) are synchronized to this object so that one call to onTick(long) won't ever occur before the previous callback is complete. This is only relevant when the implementation of onTick(long) takes an amount of time to execute that is significant compared to the countdown interval.
Take a look at this example for countdown timer
Countdown timer example
Alternately you can spawn a new thread and just get that thread to sleep for the interval you want and take actions when it wakes or vice versa.
You can also timertask
use a handler that will post the same runnable . this will remove the need for extra threads :
Handler handler=new Handler();
handler.postRunnable(... , 1000) ;
in the runnable , call the postRunnable again for the same handler (and add a condition for when to stop) .
CountDownTimer is not efficient regardless to ui updating performances. For a flawless ui update, it is better to create a custom countdown. I did my own so here it is. It is flawless on my app.
public abstract class CountDown {
int totalTime = 0;
int tickTime = 0;
Thread thread;
boolean canceled = false;
public CountDown(int totalTime,int tickTime){
this.totalTime = totalTime;
this.tickTime = tickTime;
}
public abstract void onTick();
public abstract void onFinish();
public void start(){
thread = new Thread(new Runnable() {
#Override
public void run() {
// Do in thread
canceled = false;
for (int elapsedTime = 0; elapsedTime < totalTime; elapsedTime += tickTime) {
if(!canceled){
onTick();
try {
thread.sleep(tickTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
break;
}
}
if(!canceled){
onFinish();
}
}
});
thread.start();
}
public void cancel(){
canceled = true;
}
}
Remember that every time you have to update your ui, call a runOnUiThread, or else you will have an exception, you are not in a handler and not on ui thread.
Here is how to use it in your code, it is identical to CountDownTimer, so you could just rename lines in your code :
CountDown cDown = new CountDown(10000, 20) {
public void onTick() {
// Do something
}
public void onFinish() {
runOnUiThread(new Runnable() {
#Override
public void run() {
myButton.setImageDrawable(drawable);
}
});
}
};
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);