cancelling a handler.postdelayed process - android

I am using handler.postDelayed() to create a waiting period before the next stage of my app takes place. During the wait period I am displaying a dialog with progress bar and cancel button.
My problem is I can't find a way to cancel the postDelayed task before the time elapses.

I do this to post a delayed runnable:
myHandler.postDelayed(myRunnable, SPLASH_DISPLAY_LENGTH);
And this to remove it: myHandler.removeCallbacks(myRunnable);

In case you do have multiple inner/anonymous runnables passed to same handler, and you want to cancel all at same event use
handler.removeCallbacksAndMessages(null);
As per documentation,
Remove any pending posts of callbacks and sent messages whose obj is
token. If token is null, all callbacks and messages will be removed.

Another way is to handle the Runnable itself:
Runnable r = new Runnable {
public void run() {
if (booleanCancelMember != false) {
//do what you need
}
}
}

Here is a class providing a cancel method for a delayed action
public class DelayedAction {
private Handler _handler;
private Runnable _runnable;
/**
* Constructor
* #param runnable The runnable
* #param delay The delay (in milli sec) to wait before running the runnable
*/
public DelayedAction(Runnable runnable, long delay) {
_handler = new Handler(Looper.getMainLooper());
_runnable = runnable;
_handler.postDelayed(_runnable, delay);
}
/**
* Cancel a runnable
*/
public void cancel() {
if ( _handler == null || _runnable == null ) {
return;
}
_handler.removeCallbacks(_runnable);
}}

It worked for me when I called CancelCallBacks(this) inside the post delayed runnable by handing it via a boolean
Runnable runnable = new Runnable(){
#Override
public void run() {
Log.e("HANDLER", "run: Outside Runnable");
if (IsRecording) {
Log.e("HANDLER", "run: Runnable");
handler.postDelayed(this, 2000);
}else{
handler.removeCallbacks(this);
}
}
};

Related

Handler not stopping - Android

I created one handler to repeat a task repeatedly and I also want to destroy it within that handler once a condition has been met.
pinHandler = new Handler();
Now I created two functions separately to start and stop the task.
void startRepeatingPins() {
mPinSetter.run();
}
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
try{
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
}
}
finally {
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};
private void stopUpdatingPins()
{
pinIndexCount=0;
pinHandler.removeCallbacks(mPinSetter);
System.out.println("Called the stop function.");
}
Now, the issue is that, if I call the stopUpdatingPins function , the handler stops but when I try to stop it automatically from within the handler, it just doesn't stop. Although the stopUpdatingPins function does get called.
Change You startRepeatingPins() like this, You should not directly call the run. If your run like this then there is no point of removing this from Handler. So attach Runnable with Handler.
void startRepeatingPins() {
pinHandler.post(mPinSetter);
}
You added post delay in finally that means you are stopping at first if loop and starting again in finally, So it's never stopping. So Change your runnable like this,
Runnable mPinSetter = new Runnable() {
#Override
public void run() {
System.out.println("PinIndwx count is :"+pinIndexCount);
if(pinIndexCount==(plist.size()-1))
{
stopUpdatingPins();
pinIndexCount=0;
//pinHandler.removeCallbacks(mPinSetter);
System.out.println("Handler stopped by itself.");
}
else
{
updatePoint(plist.get(pinIndexCount));
pinIndexCount++;
pinHandler.postDelayed(mPinSetter, pinInterval);
}
}
};

What code do i implement to have a time limit in my game

I'm createing a quiz that has a time limit and i dont know what to implement to have a timelimit in my level 1 class. what should i implement? can you show me a complete code?
am i correct?
private Runnable task = new Runnable() {
public void run() {
Intent intent = new Intent(getApplicationContext(),MainMenu.class);
startActivity(intent);
}
};
private void onCreate() {
Handler handler = new Handler();
handler.postDelayed(task, 60000);
There are different ways to do it. One way is to use a Runnable and a Handler.
First, define the Runnable:
private Runnable task = new Runnable() {
public void run() {
Log.i(TAG, "Time limit reached!");
// Execute code here
}
};
Then you call it (say at the start of the level, onCreate) with this Handler and postDelayed
Handler handler = new Handler();
handler.postDelayed(task, 60000);
The code within the run() method of the Runnable will execute 60 seconds after you call postDelayed
If you need regular notifications you can also use a CountDownTimer

How to run an async task for every x mins in android?

how to run the async task at specific time? (I want to run it every 2 mins)
I tried using post delayed but it's not working?
tvData.postDelayed(new Runnable(){
#Override
public void run() {
readWebpage();
}}, 100);
In the above code readwebpage is function which calls the async task for me..
Right now below is the method which I am using
public void onCreate(Bundle savedInstanceState) {
readwebapage();
}
public void readWebpage() {
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute("http://www.google.com");
}
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response1 = "";
response1=read();
//read is my another function which does the real work
response1=read();
super.onPostExecute(response1);
return response1;
}
protected void onPostExecute(String result) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
TextView tvData = (TextView) findViewById(R.id.TextView01);
tvData.setText(result);
DownloadWebPageTask task = new DownloadWebPageTask();
task.execute(new String[] { "http://www.google.com" });
}
}
This is what I my code is and it works perfectly fine but the big problem I drains my battery?
You can use handler if you want to initiate something every X seconds. Handler is good because you don't need extra thread to keep tracking when firing the event. Here is a short snippet:
private final static int INTERVAL = 1000 * 60 * 2; //2 minutes
Handler mHandler = new Handler();
Runnable mHandlerTask = new Runnable()
{
#Override
public void run() {
doSomething();
mHandler.postDelayed(mHandlerTask, INTERVAL);
}
};
void startRepeatingTask()
{
mHandlerTask.run();
}
void stopRepeatingTask()
{
mHandler.removeCallbacks(mHandlerTask);
}
Note that doSomething should not take long (something like update position of audio playback in UI). If it can potentially take some time (like downloading or uploading to the web), then you should use ScheduledExecutorService's scheduleWithFixedDelay function instead.
Use Handler and PostDelayed:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
readWebpage();
handler.postDelayed(this, 120000); //now is every 2 minutes
}
}, 120000); //Every 120000 ms (2 minutes)
you can use TimerTask instead of AsyncTask.
ex:
Timer myTimer = new Timer("MyTimer", true);
myTimer.scheduleAtFixedRate(new MyTask(), ASAP, TWO_MINUTES);
private class MyTask extends TimerTask {
public void run(){
readWebPage();
}
}
When phone goes to sleep mode, to save battery, and it is quite possible to happen within 2 mins interval, Handler.postDelayed() may miss scheduled time. For such activities you should use AlarmManager, get a lock with PowerManager to prevent going to sleep back while you're running the AsyncTask.
See my post with code sample here
Also you may want to read Scheduling Repeating Alarms
I suggest to go with Handler#postDelayed(Runnable). Keep in mind that this method will work only when your app is running (may be in background) but if user closes it manually or simply Android runs out of memory it'll stop working and won't be restarted again later - for that you need to use services.
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
/* your code here */
}
}, 2 * 60 * 1000); // first run after 2 minutes
This code will wait 2 minutes, execute your code, and then keep doing that every 2 minutes. But if you want it to run instantly for the first time - and then start the wait-do loop, instead use:
final Handler handler = new Handler();
/* your code here */
new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
/* and also here - your code */
}
}.run();
or, if your code is longer than just one method (readWebsite() in this case), and you don't want that to be duplicated:
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
/* your longer code here */
}
}, 0); // first run instantly
(^ this one is just like the first example but has a 0ms delay before first run instead of 2 minutes)
(This answer is based on #Devashish Mamgain's one but I added too much details for an edit so I had to add a new one)
Try extending the Thread class, set a sleep time of 2000 millis and place your call into the run method. That should do it.
Execute multiple messages(Runnables) then he should use the Looper class which is responsible for creating a queue in the thread. For example, while writing an application that downloads files from the internet, we can use Looper class to put files to be downloaded in the queue. This will help you to perform async task in android...
HandlerThread hThread = new HandlerThread("HandlerThread");
hThread.start();
Handler handler = new Handler(hThread.getLooper());
final Handler handler1 = new Handler(hThread.getLooper());
final long oneMinuteMs = 60 * 1000;
Runnable eachMinute = new Runnable() {
#Override
public void run() {
Log.d(TAG, "Each minute task executing");
handler1.postDelayed(this, oneMinuteMs);
sendPostRequest();
}
};
// sendPostRequest();
// Schedule the first execution
handler1.postDelayed(eachMinute, oneMinuteMs);
You can use Time with Handler and TimerTask
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask backtask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
//To task in this. Can do network operation Also
Log.d("check","Check Run" );
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(backtask , 0, 20000); //execute in every 20000 ms*/
You can check logcat to verify whether is running or not using 'check' tag name
You could run a loop within the AsyncTask that sleeps for two seconds between doing the tasks. Something like this:
protected Result doInBackground (Params... params) {
while (!interrupted) {
doWork();
Thread.sleep(2000);
}
}

How to cancel a handler before time in Android code?

I create 1 minute delayed timer to shutdown service if it's not completed. Looks like this:
private Handler timeoutHandler = new Handler();
inside onCreate()
timeoutHandler.postDelayed(new Runnable()
{
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
}, 60 * 1000);
If I get job accomplished before this 1 minute - I would like to get this delayed thing cancelled but not sure how.
You can't really do it with an anonymous Runnable. How about saving the Runnable to a named variable?
Runnable finalizer = new Runnable()
{
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
};
timeoutHandler.postDelayed(finalizer, 60 * 1000);
...
// Cancel the runnable
timeoutHandler.removeCallbacks(finalizer);
If you don't want to keep a reference of the runnable, you could simply call:
timeoutHandler.removeCallbacksAndMessages(null);
The official documentation says:
... If token is null, all callbacks and messages will be removed.
You might want to replace use of postDelayed with use of sendMessageDelayed like so:
private Handler timeoutHandler = new Handler(){
#Override
public void handleMessage(Message msg)
{
switch (msg.what){
case 1:
((Runnable)msg.obj).run();
break;
}
}
};
Then post a Message:
Message m = Message.obtain();
m.what = 1;
m.obj = new Runnable(){
public void run()
{
Log.d(LOG_TAG, "timeoutHandler:run");
DBLog.InsertMessage(getApplicationContext(), "Unable to get fix in 1 minute");
finalizeService();
}
};
timeoutHandler.sendMessageDelayed(m, 60 * 1000);
and then cancel:
timeoutHandler.removeMessages(1);
No tracking of the runnable necessary.
If I get job accomplished before this 1 minute - I would like to get this delayed thing cancelled but not sure how.
Use Handler.removeCallbacks(yourRunnable).

looper.prepare question

i am trying to loop a toast inside a timer but the toast doesn't show
the log in logcat shows that cannot create handler inside thread that has not called looper.prepare() i am not sure what it means
int initialDelay = 10000;
int period = 10000;
final Context context = getApplicationContext();
TimerTask task = new TimerTask()
{
public void run()
{
try
{
if (a != "")
{
Toast toast = Toast.makeText(context, "Alert Deleted!", Toast.LENGTH_SHORT);
toast.show();
}
}
catch (Exception e)
{
}
}
};
timer.scheduleAtFixedRate(task, initialDelay, period);
what my application does is that every 10 sec it would check if a certain variable is empty. if it is empty then it will show a toast.
i have no problem doing this in a service class but when i try to implement this into
public void onCreate(Bundle savedInstanceState)
i get this error
You're calling it from a worker thread. You need to call Toast.makeText() (and most other functions dealing with the UI) from within the main thread. You could use a handler, for example.
see this answer....
Can't create handler inside thread that has not called Looper.prepare()
You can show this toast in alternative ways also
class LooperThread extends Thread {
public Handler mHandler;
#Override
public void run() {
Looper.prepare();
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop();
}
}
Now as you see this handler is created in normal thread so if you try n send any message from it , it will throw an exception so by bounding it with Looper.prepare() and Looper.loop() you can make any statements executed within it on UI thread
Another Example
Looper allows tasks to be executed sequentially on a single thread. And handler defines those tasks that we need to executed. It is a typical scenario that I am trying to illustrate in example:
class SampleLooper {
#Override
public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();
// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
handler = new Handler();
// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
} catch (Throwable t) {
Log.e(TAG, "halted due to an error", t);
}
}
}
Now we can use the handler in some other threads(say ui thread) to post the task on Looper to execute.
handler.post(new Runnable()
{
public void run() {`enter code here`
//This will be executed on thread using Looper.`enter code here`
}
});
On UI thread we have an implicit Looper that allow us to handle the messages on ui thread.

Categories

Resources