Pausing timer without destroy and re-create - Android - android

I have this AsyncTask, that sleeps 0.1 second each time that executes "doInBackground", before that I was using a CountDownTimer to control my time.
My problem is: I want to achieve a timer that can Pause without calling .cancel() and when starts creating another timer.
Is there a way to achieve this is android? I didn't found how to do it in a different way. Can you example it?
Where I've found examples canceling the timer:
How to stop the Timer in android?
Android timer? How-to?
http://www.androidhub4you.com/2013/04/countdown-demo-in-android-custom-timer.html
EDIT
Answering Kevin Krumwiede: This project is a kind of game, that I must hit blocks in a determinated time, so I want to achieve a way to stop the timer when the player use some kind of special power (hit a button specified).
EDIT2
Answering Kushal: I don't know if you have compiled this code, but I can't use the task1 variable. Here goes the code:
public void doIt(){
final ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
final Runnable task =
new Runnable() {
#Override
public void run() {
timerAsyncTask.execute();
if(true) {
exec.shutdown(); // shutdown this execution
//exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS);
}
}
};
exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS);
}
Here exec = Executors.newSingleThreadScheduledExecutor(); it shows me an error:
Error:(33, 21) error: cannot assign a value to final variable exec
What I think it's pretty okay, once the exec is a final variable.
And here exec.scheduleAtFixedRate(task, 0, 100, TimeUnit.MILLISECONDS); I got another error:
Error:(34, 46) error: variable task might not have been initialized
Can you explain, how can I use this piece of code? I'm quite new to android.
Thanks.

I suggest you avoid Timers in Android altogether. Android has a light weight and better solution called Handler
You can find a comparison between these two here. To sum up
Comparison Handler VS Timer
While rescheduling Handler is very easy, you can not reschedule Timer
In Handler you can attach to any Runnable but Timer schedule for only
one TimerTask
TimerTask is purely background task so you can not update
UserInterface, but that's not true for Handler's Runnables
Timer Causes Execptions
Timer tends to leak more memory compare to Handler see the graph of
object retains by timer and Handler. It will increase rapidly for
Timer if you are creating and scheduling new task.
As the post suggests, the Handler usage is pretty simple. Here is an example code
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.v7.app.AppCompatActivity;
public class TestActivity extends AppCompatActivity {
private static int INITIAL_TIMER_DELAY = 100;
private static int TIMER_PERIOD = 100;
private android.os.Handler handler;
private Runnable runnable;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler(Looper.getMainLooper());
runnable = new Runnable() {
#Override
public void run() {
// Do something and reschedule ourself
handler.postDelayed(this, TIMER_PERIOD);
}
};
handler.postDelayed(runnable, INITIAL_TIMER_DELAY);
}
#Override
protected void onDestroy() {
super.onDestroy();
cancelTimer();
}
private void cancelTimer() {
if (handler != null) {
handler.removeCallbacks(runnable);
}
}
private void rescheduleRunnable() {
handler.postDelayed(runnable, INITIAL_TIMER_DELAY)
}
}

You can achieve your requriment using ScheduledExecutorService class
Basic difference between ScheduledExecutorService and Timer class is :
Using Timer class, you cannot check how your execution is going. You can start and stop execution but cannot check execution based on condition
ScheduledExecutorService provides way to check how execution is running in between start and stop call. If any execution of the task encounters an exception, subsequent executions are suppressed
How we can achieve your requirement :
We need 0.1 second delay between doInBackground() execution
We shall be able to pause our execution when other execution starts
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
Runnable task1 = new Runnable() {
public void run() {
// start your AsyncTask here
new <your_task>().execute();
if (<check_your_condition_when_to_pause>) {
exec.shutdown(); // shutdown this execution
exec = Executors.newSingleThreadScheduledExecutor();
exec.scheduleAtFixedRate(task1, 0, 100, TimeUnit.MILLISECONDS);
// here i have passed task1 for example
// here we need to pass next task runnable which
// we want to run after 0.1 seconds
} else {
// continue normal
}
}
};
exec.scheduleAtFixedRate(task1, 0, 100, TimeUnit.MILLISECONDS);
Credit reference : Answer 1 and Answer 2
I hope this will help to solve some of your doubts

Related

Call ExectuorService with time interval - android

i used a custom thread to fetch data in the background every 1 second by making a thread goes to sleep, but my App crashes and throws exception OutOfMemoryError. Now i read a documentation in android developer and i understand that using custom thread is bad practice as it is difficult to manage the memory consistency. but finally i found ExecutorService very interesting when we need to do some tasks on background So, i decided to use it.
As You know the ExecutorService is like below:
public void executeTask()
{
ExecutorService executroService = new Executor.newSingleThreadExecutor();
executroService.execute(new Runnable()
{
#Override
publi void run()
{
// now execute the server request
}
});
}
Now how can i achive calling to executorService every 1 second untill the user goes to onpause() state or untill the user shifts from the current activity to another activity? if i use a custom thread to call that service, the App goes to crash. so how can i achive that ?
What you need is a ScheduledExecutorService
It can schedule commands to run after a given delay,
or to execute periodically.
Here is a code that implements this
import static java.util.concurrent.TimeUnit.*;
class BeeperControl {
private final ScheduledExecutorService scheduler =
Executors.newScheduledThreadPool(1);
public void beepForAnHour() {
Runnable beeper = () -> System.out.println("beep");
ScheduledFuture<?> beeperHandle =
scheduler.scheduleAtFixedRate(beeper, 10, 10, SECONDS);
Runnable canceller = () -> beeperHandle.cancel(false);
scheduler.schedule(canceller, 1, HOURS);
}
}

What is the way to make an infinite loop in a thread? android

I want to make an infinite loop in android, to check if some apps are active.
What is the best way to do this without using too much cpu?
Maybe a while loop or a handler or something?
Thanks,
Peter
Use a Handler:
import android.os.Handler;
// Create the Handler
private Handler handler = new Handler();
// Define the code block to be executed
private Runnable runnable = new Runnable() {
#Override
public void run() {
// Insert custom code here
// Repeat every 2 seconds
handler.postDelayed(runnable, 2000);
}
};
// Start the Runnable immediately
handler.post(runnable);
To remove the execution of the runnable:
handler.removeCallbacks(runnable);
You could do something like
while(true)
Just make sure to use a break when you want to exit.
You also could do something like this:
boolean run = true;
while(run)
{
if()//Whatever you want to cause the loop to stop.
{
run = false;
}
}
I would not use an infinite loop in a thread. I would use a scheduled task like this. From SO
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
scheduler.scheduleAtFixedRate(yourRunnable, 8, 8, TimeUnit.HOURS);
Then you can customize how frequently you want it to run by changing the TimeUnit to however frequently you need the thread to run.

Call an async task repeatedly (lets say every 10 seconds) using tasktimer

My requirement is to call an async task repeatedly every 10 seconds so that the webservice will fetch data an do the update (updating of a map and image) accordingly.
I searched throughout and found out that one can use a tasktimer for this. The problem I am facing is that a parameter is passed into my asynctask. But I am not able to pass that parameter into the tasktimer.
I found out that for this a separate class should be created which extends timer task. But I have no idea how to get that done according to my need.
Please be kind enough to help me. The code for passing a parameter to the async task is given below.
new AsyncLoadGpsDetails().execute(userName);
I want to repeatedly perform the async task. PLease help me, I don't know how to create the class which extends tasktimer as I'm a newbie to this.
Thanks & Regards in advance
You can use either use scheduleAtFixedRate or scheduleWithFixedDelay...
scheduleAtFixedRate
// this task for specified time it will run Repeat
repeatTask.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
// Here do something
// This task will run every 10 sec repeat
}
}, 0, 10);
scheduleWithFixeDelay
scheduler.scheduleWithFixedDelay(new TimerTask() {
#Override
public void run() {
// Here do something
// This task will run every 10 sec Delay
}
},, 0, 10, TimeUnit.SECONDS);
Find the difference between them Here
Here is an example of a Timer and TimerTask:
private Timer mTimer;
private TimerTask mTimerTask;
private void launchTimerTask() {
mTimer = new Timer();
mTimerTask = new TimerTask() {
#Override
public void run() {
// Perform your recurring method calls in here.
new AsyncLoadGpsDetails().execute(userName);
}
};
mTimer.schedule(mTimerTask, // Task to be executed multiple times
0, // How long to delay in Milliseconds
10000); // How long between iterations in Milliseconds
}
private void finishTimerTask() {
if (mTimerTask != null) {
mTimerTask.cancel();
}
if (mTimer != null) {
mTimer.purge();
mTimer.cancel();
}
}
For the TimerTask you will need the following imports:
import java.util.Timer;
import java.util.TimerTask;
If possible, I would use a ScheduledExecutor (Java Timer vs ExecutorService?). There are many examples around, but here is a quick snippet:
private ScheduledExecutorService mService;
private ScheduledFuture mFuture;
private void launchScheduledExecutor() {
mService = Executors.newSingleThreadScheduledExecutor();
mFuture = mService.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
// Perform your recurring method calls in here.
new AsyncLoadGpsDetails().execute(userName);
}
},
0, // How long to delay the start
10, // How long between executions
TimeUnit.SECONDS); // The time unit used
}
private void finishScheduledExecutor() {
if (mFuture != null) {
mFuture.cancel(true);
}
if (mService != null) {
mService.shutdown();
}
}
Be sure to shutdown the ExecutorService when you're done.
For the above snippet you'll need the following imports:
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
You can call launch anywhere (an onClickListener or onCreate perhaps). Just be sure to call 'finish' at some point or they will run indefinitely (in the onDestroy for example)

Taking a picture with 2 secs of delay

Is there a way to take a picture two seconds after the Camera.takePicture method is invoked? For some reason, I do not want to use handler/timer to schedule the invocation of takePicture.
Precisely, I would like to use a different solution than the following one:
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
<here takePicture is invoked>
}
});
}
}, 2000);
You could use AlarmManager with a PendingIntent and handle taking the camera capture in your Activity.onNewIntent method, but it is a very confusing solution for what you are trying to solve (a much better use of AlarmManager is to schedule tasks so that they are performed even if the user exits your application). This solution also requires more code and is less precise/reliable and less efficient than using a Handler.
EDIT: You can also use a ScheduledThreadPoolExecutor along with a Runnable.
(Personal opinion following) If you are exploring the APIs available in Android for performing timed tasks, that is ok, but I wouldn't use AlarmManager to schedule timed tasks within an Activity that's already running.
If you just want to have the code a bit more organised, you can make an inner class that implements Runnable and schedule your action like this:
class MyCameraActivity extends Activity
{
class TakePictureTask implements Runnable
{
public void run()
{
MyCameraActivity.this.takePicture();
}
}
void scheduleCameraShot()
{
(new Handler(this.getMainLooper())).postDelayed(new TakePictureTask(), 2000);
}
}

Destroying Runnable in android

I am using the following code to access a url:
final Handler handler = new Handler();
Runnable runnable = new Runnable()
{
public void run()
{
img.setImageBitmap(returnBitmap("fromurl"));
handler.postDelayed(this, 50);
}
};
handler.postDelayed(runnable, 2000);
I observed that if the server is not up the app takes ages to close correctly if I hit the back button. Is there anyway way I could speed up the exit procedure.
Runnables will exit automatically when finished with their run() method. If you are employing a loop to do some work, the solution that Jay Ho suggested will help exit from the loop cleanly. If you want to prevent the Handler from executing the runnable (before it posts) you can use handler.removeCallbacksAndMessages(null)1 to clear the queue. Placing it in onDestroy() is your best bet. Otherwise, you're on your own. Once you've spawned a thread, you're at the mercy of the Android operating system to terminate it once its done.
Side note: I've run into problems like this before, and it's usually a call to a system service or the implementation of a Broadcast Listener or Alarm that mucks up the exit process.
private Runnable runnable = new Runnable() {
private boolean killMe=false;
public void run() {
//some work
if(!killMe) {
img.setImageBitmap(returnBitmap("fromurl"));
handler.postDelayed(this, 50);
}
}
public void kill(){
killMe=true;
}
};
ThreadPoolExecutor threadPoolExecutor = Executors.newSingleThreadExecutor();
Runnable longRunningTask = new Runnable();
// submit task to threadpool:
Future longRunningTaskFurure = threadPoolExecutor.submit(longRunningTask);
... ...
// At some point in the future, if you want to kill the task:
longRunningTaskFuture.cancel(true);
... ...

Categories

Resources