I need to call the speak method every 5 minutes, then i want to run in background the async method called callspeak, that calls back the speak method(a public method of a different class). It has to loop every 5 minutes
class callSpeak extends AsyncTask<String, Void, String> {
activityAudio a = new activityAudio();
#Override
protected String doInBackground(String... strings) {
try
{
while (true){
a.speak();
Thread.sleep(300000);
}
}
catch (InterruptedException e)
{e.getMessage();}
return null;
}
}
If you want to run the method only when the app is open, you can simply use TimerTask.
Timer myTimer = new Timer ();
TimerTask myTask = new TimerTask () {
#Override
public void run () {
// your code
callSpeak().execute() // Your method
}
};
myTimer.scheduleAtFixedRate(myTask , 0l, 5 * (60*1000)); // Runs every 5 mins
If you want to run it in background even if app is not running, you can use AlarmManager and repeat the task every 5 mins.
Hope it helps
You can do like this:
Handler mHandler = new Handler();
Runnable mRunnableTask = new Runnable()
{
#Override
public void run() {
doSomething();
// this will repeat this task again at specified time interval
mHandler.postDelayed(this, yourDesiredInterval);
}
};
// Call this to start the task first time
mHandler.postDelayed(mRunnableTask, yourDesiredInterval);
Don't forget to remove the callbacks from handler when you no longer need it.
The latest and the most efficient way to perform this, even if you come out of the activitiy or close the app is to implement the WorkManager from the AndroidX Architecture.
You can find more details here from the official documentation: Schedule tasks with WorkManager
Related
BuzzerControl function is a function that sounds buzzer. I want this function to blink once every three seconds. What should I do? I tried sleep function but it doesn't work.
While(true){
BuzData=1;
BuzzerControl(BuzData);
}
First, we need a Handler that starts the Runnable after 3000ms i.e 3seconds
private Handler handler = new Handler();
handler.postDelayed(runnable, 3000);
And we also need the Runnable for the Handler
private Runnable runnable = new Runnable() {
#Override
public void run() {
/* do what you need to do */
foobar();
/* and here comes the "trick" */
handler.postDelayed(this, 3000);
}
Note:There’s also another advantage of this solution: You don’t have
to create new Timer(Task)s all the time and can reuse the one Handler
and Runnable.
When I start the app "specific function" needs to be executed.
After 10 seconds "specific function" needs to be triggered again.
After this second operation "specific function" should not triggered again.
There are two way to handle your problem.
If there is any condition you want to check and accordingly do the work after every 10 seconds You should Use a Handler.
If there is no condition on anything and you just want to run the code after every 10 Seconds. Then TimerTask is also one way. I have actually worked with TimerTask class. So i say it is quite easy.
Creating your class and implementing the methods.
class myTaskTimer extends TimerTask{
#Override
public void run() {
Log.e("TAG", "run: "+"timer x");
}
}
and now in your code Create a new Timer Object and initialize it.
Timer t = new Timer();
Now you can schedule your task in it after a specified interval like below:
t.scheduleAtFixedRate(new myTaskTimer(),10000,10000);
The function is explained below:
void scheduleAtFixedRate (TimerTask task,
long delay,
long period)
Schedules the specified task for repeated fixed-rate execution,
beginning after the specified delay. Subsequent executions take place
at approximately regular intervals, separated by the specified period.
and now for handler , below is the code and it can check for any condition. Code taken from here for your help.
private int mInterval = 10000; // 10 seconds as you need
private Handler mHandler;
#Override
protected void onCreate(Bundle bundle) {
// your code here
mHandler = new Handler();
startRepeatingTask();
}
#Override
public void onDestroy() {
super.onDestroy();
stopRepeatingTask();
}
Runnable mStatusChecker = new Runnable() {
#Override
public void run() {
try {
updateStatus(); //this function can change value of mInterval.
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
mHandler.postDelayed(mStatusChecker, mInterval);
}
}
};
void startRepeatingTask() {
mStatusChecker.run();
}
void stopRepeatingTask() {
mHandler.removeCallbacks(mStatusChecker);
}
I hope it helps.
Use android.os.Handler as per #pskink comment.
private void callSomeMethodTwice(){
context.myMethod(); //calling 1st time
new Handler().postDelayed(new Runnable(){
#Override
public void run(){
context.myMethod(); //calling 2nd time after 10 sec
}
},10000};
}
The version of Java is 8u60.
I want to write a void method which could pause the program for 1 seconds but there are always exceptions.
public void OnePause(){
Timer timerOne = new Timer();
timerOne.schedule(timerOneTask(), (long)1000);}
private TimerTask timerOneTask() {
return null;
}
}
I do not want to use Thread.Sleep(); because it pauses the sum of all time when called multiple times instead of pause separately.
Thanks a lot.
Right now your code is broken. Besides trying to send null into Timer.schedule(...), your statement timerOne.schedule(timerOneTask(), (long)1000);} is going to call timerOneTask() every 1000 milliseconds, but that does not pause the program. You must sleep the thread:
private TimerTask timerOneTask(int sleepTime) {
return new DoNothingTimerTask extends TimerTask {
public void run() {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// awoken prematurely, handle this
}
}
}
Unless you need to schedule the "pauses" on some interval, there's no use in introducing the Timer API into the mix; if not, you can get simply use what's in that try...finally block.
I'm working on a Minecraft Bukkit plugin, I know how to handle events and everything, but I'm not sure how to do this. I haven't actually written the code yet so here's a basic example of what I want to do:
public void playerDead() {
runCommand(commandHere)
//Wait 2 minutes.
runCommand(otherCommandHere
}
I just need the part to wait two minutes. Everything else is covered.
EDIT2: Seems I need to reset the delay to the beginning if someone else dies while it's going. Any suggestions?
Since I see you want to perform your action after the player has died. Then for sure you don't want to halt the main Thread with Thread.sleep(x);
What you can do is create a cooldown for the player that passed away.
public Map<String, Long> cooldown = new HashMap<String, Long>();
Long time = cooldown.get(player.getName());
if(time - System.currentTimeMillis() > 10*1000)
cooldown.put(player.getName(), System.currentTimeMillis());
else
int remains = (int)Math.floor(10 - System.currentTimeMillis());
Code reference here.
Or you can create your task to run like this:
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
public void playerDied()
{
// Your code here.
}
}, <delay in ticks>);
Get a reference to your plugin and pass it as the parameter plugin. Or if you are lazy just write it inside the plugin and pass it this.
You should use the BukkitScheduler provided by Bukkit.
You have to save the BukkitTask object returned by the Scheduler.runTaskLater(...) method to use it later.
Every time playerDead() is called, you can reset the delay by cancelling and restarting the task.
BukkitTask task;
public void playerDead() {
// Command here
if (task != null) {
task.cancel();
}
task = getServer().getScheduler().runTaskLater(Plugin, new Task(), 2400L);
}
public class Task extends BukkitRunnable {
#Override
public void run() {
// Other command here
task = null;
}
}
You may try like this:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
runCommand(commandHere);
}
}, 120000);
This could be a duplicate question but I did not find what I was looking for.
I am calling an AsyncTask in the UI activity new LoadData().execute(); and in doInBackground I call a method which takes time. I want to interrupt this thread if the data is not return after some time.
Below is the code how I tried to do this.
class LoadData extends AsyncTask<String, String, String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
startTime = System.currentTimeMillis();
}
protected String doInBackground(String... args)
{
DataCollector dc = new DataCollector();
data = dc.collectData(query);
//Here I check if the time is greater than 30 seconds then cancel
if(((System.currentTimeMillis()-startTime)/1000)>30)
{
cancel(true);
}
return null;
}
}
But this does not stop the task after 30 seconds, in fact it is taking more time.
I have tried get(long timeout, TimeUnit unit); as well but that does not work either.
Can anyone show me how can I do it or how do I use isCancelled() in doInBackground.
Thanks.
You need a thread that cancels your task after a certain amount of time. That Thread could look like this:
public class TaskCanceler implements Runnable{
private AsyncTask task;
public TaskCanceler(AsyncTask task) {
this.task = task;
}
#Override
public void run() {
if (task.getStatus() == AsyncTask.Status.RUNNING )
task.cancel(true);
}
}
And when you call your AsyncTask, you need to run the cancle task after a certain amount of time (=the timeout, in this case 20 sec)
private Handler handler = new Handler();
private TaskCanceler taskCanceler;
...
LoadData task = new LoadData();
taskCanceler = new TaskCanceler(task);
handler.postDelayed(taskCanceler, 20*1000);
task.execute(...)
It's a good idea if you clean this up on cancel or finish with
if(taskCanceler != null && handler != null) {
handler.removeCallbacks(taskCanceler);
}
You can of course wrap this in an custom implementation of AsyncTask. I've used this pattern many times and it works like a charm. One thing to note, in rare cases the handler would not start, I suspect if you create it in the wrong context it will not survive in certain instances, so I forced the handler to be an the UI Thread with handler= new Handler(Looper.getMainLooper());
You have to do the Time check on a different thread.
What you currently do is: executing the dc.collectData(query) (in background) and once it is ready you check if you should cancel. So if the query takes 1 minute, you will do the cancel check after 1 minute, which is already too late.
What you could do is schedule a TimerTask that should run 30 seconds after the LoadData().execute() and if the timer Task is run, you can cancel the AsyncTask (if it is still running)
I would translate this into an async/await problem making all the expensive methods as async methods.
First, Modify DataCollector's collectData(query) to collectDataAsync(query). (If you can't modify DataCollector, there are work arounds to wrap it in a lambda function or something similar).
Second, change doInBackground as an async task, something like this:
protected async Task<String> doInBackgroundAsync(String... args)
{
DataCollector dc = new DataCollector();
int timeout = 1000;
var task = dc.collectDataAsync(query);
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
// task completed within timeout
data = task.Result;
} else {
// timeout logic
}
}
Basically, you have two tasks inside doInBackgroundAsync: collectDataAsync and a delay task.
Your code waits for the faster one. Then you know which one was and you can react accordingly.
If you also need to cancel collectDataAsync task, then you want to used a cancellationToken.
I use this to solve your problem https://stackoverflow.com/a/11191070/3307066.
Note that now doInBackgroundAsync is a async, so it changes a bit the way of using it.
Hope it helps.
Short answer is you CAN'T cancel an AsyncTask once its started. What you can do, is insert a loop inside doInBackGround() which will check for isCancelled() and if it is set to true sometime in the future - return a value from the function (which will in turn call onPostExecute() if you have defined it);
Note that just because you can't stop an AsyncTask doesn't mean that the OS won't cancel it if it's low on memory. You should have this in mind if you are doing essential tasks in the AsyncTask (ones that you want executed 100%). If so, it is better to use a Service - a component that is automatically killed and restarted by the OS as need.
try this :
public class MyTask extends AsyncTask<Void, Void, Void> {
private volatile boolean running = true;
private final ProgressDialog progressDialog;
public MyTask(Context ctx) {
progressDialog = gimmeOne(ctx);
progressDialog.setCancelable(true);
progressDialog.setOnCancelListener(new OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// actually could set running = false; right here, but I'll
// stick to contract.
cancel(true);
}
});
}
#Override
protected void onPreExecute() {
progressDialog.show();
}
#Override
protected void onCancelled() {
running = false;
}
#Override
protected Void doInBackground(Void... params) {
while (running) {
// does the hard work
}
return null;
}
// ...
}
Courtesy and for more details see this answer.