Android Runnable not stopping after removeCallbacks() - android

I am trying to stop Runnable using removeCallbacks, but somehow it wont stop. - here are my variables
private int mInterval = 2000; // 2 seconds by default, can be changed later
private Handler mHandler = new Handler();
and my runnable
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
checkPayNow();
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
and the method I am running untill it gives me a certain value then i stop
public void checkPayNow(){
if (!url.isEmpty()){
//url now has text
mHandler.removeCallbacks(mStatusChecker);
}else {
//no text yet
}
}

boolean stoped = false;
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
checkPayNow();
} finally {
if(!stoped)
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
Make stoped = true when you want to stop.
and remove handler from checkPayNow().
public void checkPayNow(){
if (!url.isEmpty()){
//url now has text
//mHandler.removeCallbacks(mStatusChecker);
}else {
//no text yet
}
}

You can try to do it without removeCallbacks like this:
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
if(!checkPayNow()) {
//if not ready so far, then check in some delay again
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
public boolean checkPayNow(){
return !url.isEmpty();
}

Related

How to update a textview frequently with a spesific time delay?

I need to update a TextView frequently with a specific time delay in the android studio. The code is below. Thank you.
Edit: I also need to end the loop with a button click or with an "if" control.
//INFLATION CALCULATION !!!
/**
* This method calculates Inflation value.
*/
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
}
}, delay*12);
}
Call the same method inside the runnable in order to keep the loop going
Use a flag in order to be able to stop the loop: shouldCalculate
private boolean shouldCalculate = true; // set to false when you want to end the loop
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (shouldCalculate) {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
calculateInflation();
}
}
}, delay*12);
}
private Runnable updateTimerThread = new Runnable() {
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
customHandler.postDelayed(this, 0);
}
};
public void startTimer() {
//timer
startTime = SystemClock.uptimeMillis();
customHandler.postDelayed(updateTimerThread, 0);
}
public void stopTimer() {
//timer stops
customHandler.removeCallbacks(updateTimerThread);
//timer ends
}
make a reference of runnable thread , start it using startTimer() and remove thread using stopTimer() as you said on a button click or up on a specific conditions .Also you can change the postDelayed milliseconds as ur wish
Try below code. This will do the trick. If you find any problem please let me know.
public void calculateInflation() {
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
if(shouldRepeat)
calculateInflation();
}
}, delay*12);
}
And second approach can be CountDownTimer. Make a method as shown in below code
public void timerTask(final int loopTime){
//Loop time is the actual time for repeatation
new CountDownTimer(loopTime, 1000) {
public void onTick(long millisUntilFinished) {
//this tells you one second is passed
}
public void onFinish() {
//here on time finish you need to define your task
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
//call the same method again for looping
timerTask(loopTime);
}
}.start();
}
Simplest way. Here updateRunnable calls itself with delay. Make updateRunnable as global variable to access from anywhere.
Runnable updateRunnable = new Runnable() {
#Override
public void run() {
inflation = (cpi-cpiIni)/cpiIni*100;
displayInflation();
cpiIni = cpi;
handler.postDelayed(this, UPDATE_TIME);
}
};
Start handler. Here we start handler immediately without delay.
handler.postDelayed(updateRunnable, 0)
Stop handler
handler.removeCallbacks(updateRunnable)
By the way don't forget to stop handler on onDestroy()

Remove callback not working in Handler

I have Handler.I call my function every 10 second.Code working perfect,but i can't stop handler.This is my source code
handler=new Handler();
handler.post(runnable);
public Runnable runnable = new Runnable() {
#Override
public void run() {
myFunction(position);
handler.postDelayed(runnable,10000);
}
};
public void myFunction(int position)
{
if(position>10)
handler.removeCallbacks(runnable);
}
I can call myfunction every 10 second,but i can't stop handler.Ho i can solve my problem?
The problem is that myFunction removes the callback, then you still call handler.postDelayed to schedule a new one. There are plenty of ways to refactor this. For example:
handler=new Handler();
handler.post(runnable);
public Runnable runnable = new Runnable() {
#Override
public void run() {
boolean reschedule = myFunction(position);
if(reschedule) {
handler.postDelayed(runnable,10000);
}
}
};
public boolean myFunction(int position)
{
if(position>10) {
return false;
}
return true;
}
You don't have to remove callbacks on the handler because a new one will not be scheduled in the first place.
You remove callback in myFunction but you postDelayed again when myFunction returns, just invert lines inside run()
#Override
public void run() {
handler.postDelayed(runnable,10000);
myFunction(position);
}

How to make a picture that would be updated every 30 seconds?

How to make a picture that would be updated every 30 seconds ?
ImageView imageView = (ImageView) findViewById(R.id.imageView);
Picasso.with(this).load("http://i.imgur.com/DvpvklR.png").memoryPolicy(MemoryPolicy.NO_CACHE).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
You are going to want to use something like a thread to do this.
For example, below your image view:
Runnable imageUpdater = new Runnable() {
#Override
public void run() {
while (true) {
try {
sleep(30000); // 30 seconds in milliseconds
} catch(InterruptedException e) {
// Someone called thread.interrupt() and tried
// to stop the thread executing
return;
}
// Here load the image in the same way as above:
// But you will need to go onto the UI thread first.
image.post(new Runnable() {
public void run() {
Picasso.with(YourActivity.this).load( "http://i.imgur.com/DvpvklR.png").memoryPolicy(MemoryPolicy.NO_CACHE).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
}
});
}
}
};
Then you just start the runnable:
Handler handler = new Handler();
handler.post(imageUpdater);
String[] imageLink = {http://i.imgur.com/DvpvklR.png,
http://i.imgur.com/DvpvklR.png, http://i.imgur.com/DvpvklR.png};
int position = 0;
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(runnable);
}
}, 30 * 1000, 30*1000);
Runnable runnable = new Runnable() {
#Override
public void run() {
Picasso.with(this).load(imageLink[position%imageLink.length]).memoryPolicy(MemoryPolicy.NO_CACHE).networkPolicy(NetworkPolicy.NO_CACHE).into(imageView);
position++;
}
};
Hope the above code will help you :)

Should I pause my thread or not Android

So I have thread where it checks every 10ms's if drag is almost outside draggingzone. Basicly my thread code is doing nothing 99% of time so should I make it to pause and resume only when needed? Or does this literally do nothing when right and left are false?
My code looks like this
timer = new Thread() { //new thread
public void run() {
b = true;
try {
do {
sleep(10);
runOnUiThread(new Runnable() {
#Override
public void run() {
if (right) {
dragzone.moveleft(-5);
} else if (left) {
dragzone.moveleft(5);
}
}
});
}
while (b);
} catch (InterruptedException e) {
}
}
;
};
timer.start();
It looks like using a Thread here is not necessary, and you should switch to using a Handler and postDelayed()
First, declare your Handler, boolean, and a Runnable as instance variables:
Handler handler;
boolean b;
Runnable checkDragZone = new Runnable(){
#Override
public void run() {
if (right) {
dragzone.moveleft(-5);
} else if (left) {
dragzone.moveleft(5);
}
if (b){
handler.postDelayed(this, 10);
}
}
};
To start monitoring, set b to true, and start the Runnable:
handler = new Handler();
b = true;
handler.postDelayed(checkDragZone, 10);
To stop it (temporarily or permanently), just set b to false:
b = false;
It's not really a good practice to keep it running. You can start it when you detect the Drag action and then release it when it's finished.
Runnable runnable;
Thread globalThread;
public void startThread() {
if (threadController) {
runnable = new Runnable() {
#Override
public void run() {
while (threadController) {
for (int i = 0; i < adapter.getCount(); i++) {
final int value = i;
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.post(new Runnable() {
#Override
public void run() {
viewPager.setCurrentItem(value, true);
}
});
}
}
}
};
globalThread = new Thread(runnable);
globalThread.start();
} else {
return;
}
}
#Override
public void onPause() {
super.onPause();
threadController = false;
handler.removeCallbacks(runnable);
runnable = null;
if (globalThread != null) {
globalThread.interrupt();
}
}
#Override
public void onDestroy() {
super.onDestroy();
threadController = false;
}
Your resolve must be like this globalThread.interrupt();

Repeat a Method for specific times in android

Here is a code which I want to repeat 50 times after every 3 seconds. if I am calling this function with 'for' loop or 'while' loop it is not working properly Please give me suggestion.
for (int i = 0; i < 50; i++) {
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Generate_Ballon();
}
}, delay);
}
You can use CountDownTimer
See Example,
new CountDownTimer(150000, 3000)
{
public void onTick(long millisUntilFinished)
{
// You can do your for loop work here
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
Here onTick() method will get executed on every 3 seconds.
You should use Handler's postDelayed function for this purpose. It will run your code with specified delay on the main UI thread, so you will be able to update UI controls.
private int mInterval = 5000; // 5 seconds by default, can be changed later
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
...
mHandler = new Handler();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
updateStatus(); //this function can change value of mInterval.
mHandler.postDelayed(mStatusChecker, mInterval);
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
private int count = 50;
private Handler handler = new Handler();
private Runnable r = new Runnable() {
public void run() {
Generate_Ballon();
if (--count > 0) {
handler.postDelayed(r, delay);
}
}
};
handler.postDelayed(r, delay);

Categories

Resources