I have a background thread which calls 3 asynctasks to perform tasks simultaneously. The calling thread acts as a Queue for 3 sets of these tasks.
So basically I need to call 3 asynctasks simultaneously and once they are completed I want to call the next three tasks on the queue and repeat.
However I am having trouble pausing the caller thread until the three asynctask finishes. As a result the next three tasks in the queue start running before the previous three tasks are completed.
So is there anyway to hold the caller thread until the asynctasks are completed. I know that you can user .get() in asynctask but it will not enable the three asynctasks to run simultaneously.
Following code is rather a pseudocode of the idea. Basically, you'll declare an interface which will check for firing next three AsyncTasks. You'll also need to maintain a counter to see if the number of received response from AsyncTask is multiplied by 3. If it is then you can trigger next three AsyncTasks.
public interface OnRunNextThree{
void runNextThreeTasks();
}
public class MainClass extends Activity implements OnRunNextThree {
private int asyncTasksCounter = 0;
public void onCreate() {
//Initiate and run first three of your DownloadFilesTask AsyncTasks
// ...
}
public void runNextThreeTasks() {
if (asyncTasksCounter % 3 == 0) {
// you can execute next three of your DownloadFilesTask AsyncTasks now
// ...
} else {
// Otherwise, since we have got response from one of our previously
// initiated AsyncTasks so let's update the counter value by one.
asyncTasksCounter++;
}
}
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
private OnRunNextThree onRunNextThree;
public DownloadFilesTask(OnRunNextThree onRunNextThree) {
this.onRunNextThree = onRunNextThree;
}
protected Void doInBackground(Void... voids) {
// Do whatever you need to do in background
return null;
}
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//Got the result. Great! Now trigger the interface.
this.onRunNextThree.runNextThreeTasks();
}
}
}
Async tasks are meant to do things asynchronously.... so this can't be done in a straight forward way...
Even if you manage to do this, it basically defeats the whole point of asynchronous operation.
You should look for a Synchronous network operation.
Check out Volley... It is a google library specially made for network operations and it supports Synchronous operations
http://www.truiton.com/2015/02/android-volley-making-synchronous-request/
There are many other libraries available ... Retrofit is one other good library..
Related
Scenario:
The user has a list of items, let's say 10 items. Each item has an Operation button, which calls an AsyncTask which makes a web call. When a call is made, the item displays a spinner during the execution of the task
Problem:
Some of the users abuse this, and press quickly more Operation buttons, quicklt one after another, executing the web calls too often. So I want to be able to somehow, execute each of the AsyncTasks one after another with a delay of 2 seconds between executions. I do not want to switch to something else from AsyncTask if possible. So basically if there are 3 Operation buttons pressed, the execution should be:
-> Operation 1
-> 2 seconds delay
-> Operation 2
-> 2 seconds delay
-> Operation 3
-> ....
What would be the best way to do this in Android?
LE:
I have just realized something, for executing my task I ran the following code:
myTask = new MyTask();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
myTask.execute();
}
Well, I've been using this code for a lot of time now, knowing that after honeycomb the tasks were not executed in parallel anymore without using an Executor. So it seems that only doing a simple myTask.execute() and adding a Thread.sleep() makes my AsyncTasks execute, one after another just as expected.
You will need to maintain a list of the operations that needs to be performed.
on click of the button add the task in the list, call a method which check the list for the task and executes it if there is no other task is running..
in onPostExecute method call the same method to check if there is any other task / operation that needs to be performed..
It may not be the full code you require... but may give you some idea..
public class TestActivity extends AppCompatActivity {
private static boolean isTaskRunning =false;
static ArrayList<CustomTask> customTaskList = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
}
public void onBtnClick(View view)
{
// create custom task with required values and actions
CustomTask customTask = new CustomTask();
customTaskList.add(customTask);
checkAndExecuteTask();
}
private static void checkAndExecuteTask()
{
//checks if there is any task in the list and is there any other running task
if(customTaskList.size()>0 && !isTaskRunning) {
new MyAsync(customTaskList.get(0)).execute();
}
}
static class MyAsync extends AsyncTask<Void,Void,Void>
{
CustomTask currentCustomTask;
public MyAsync(CustomTask customTask)
{
currentCustomTask = customTask;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
isTaskRunning= true;
}
#Override
protected Void doInBackground(Void... voids) {
// do your stuff
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
customTaskList.remove(currentCustomTask);
isTaskRunning =false;
checkAndExecuteTask(); // task is completed so check for another task and execute (if any).
}
}
class CustomTask
{
// create class with required fields and method
}
}
There are a number of ways you can do this in android.
One way is to use a handler.
What you need to do is to, create a seperate thread and run handler.postDelayed in it.
private void startWebCall() {
Thread thread = new Thread() {
public void run() {
Looper.prepare();
final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
// Do your web calls here
handler.removeCallbacks(this);
Looper.myLooper().quit();
}
}, 2000);
Looper.loop();
}
};
thread.start();
}
You should call above method whenever user clicks a item.
Another way that I can think of is using an IntentService
An IntentService is a service that is used for doing asynchronous tasks in background. It maintains a queue of the tasks it needs to do. It is different from the above approach in the sense that it executes these tasks in a sequential order. So when you make requests to it to make web calls it will queue them, make the first call and then after it finishes it will make the second call. So the different web calls will not execute in parallel. They will execute in a sequential order but in a different thread. Also it is a service so it can run even in the background, i.e if user closes the app.
This is a good tutorial to get start with IntentService.
AsyncTaks should be generally avoided unless the work one needs to do is quite trivial. This blog explains its pitfalls.
I have a loading activity which makes few requests to server and converts data.
And layout of this activity is just simple logo image and progressBar.
All my operations were made in onCreate() and according to received request from server I start different activities:
if (request == 1) { start activity A}
else { start activity B}
The problem is loading takes 2-3 sec and operations are made even before onResume(), before activity's view come to UI.
So its just blank activity which does some work.
How can I ensure that those operations are made only after activity complete its creation?
If i clearly understand you you want to start activity 0 in which onCreate function is doing internet requests and after getting feedback from it you decide to call activity A or B. Is that correct? If yes you need to do network request in backgroud so your user interface thread doesnt freez. You can use AsyncTask for example and on it's onPostExecute method decide to fire acitivty A or B
EDIT
private class YourAsyncTask extends AsyncTask<String, Long, String> {
protected Long doInBackground(String... params) {
//here is background thread work calling net API request, hard working etc... but you can't touch UserInterface thread, since we are in background
//here call your API and parse answear
String ret = flag
return flag;
}
protected void onProgressUpdate(Long... progress) {
}
protected void onPostExecute(String result) { //here you are getting your flag from doInBackground as a result parameter
// this is executed after doInBackground, fired automatically and run on User interface thread here you can for example modify layout so you can run activity A OR B
}
}
and if you have your logic in AsyncTask you can run it from onCreate for example it doesn't matter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_layout);
new YourAsyncTask().execute();
}
So you layot will be displayed and after executed your onPostExecute will be called
You need to move that server call off the main ui thread. Use an IntentService or something similar.
What I understand from this question, you must be using AsyncTask or Service to connect to server. You put the main thread in while loop and AsyncTask or Service is doing the required operation for you. After operation is complete, it will break out of while loop and then use if/else loop and decide which activity to start next.
Something like this:
public void onCreate(Bundle savedInstanceState)
{
boolean isDone = false;
// initialization code here
// start AsyncTask
BackgroundThread.execute(params);
while(!isDone)
{
Thread.sleep(1000); // 1 sec
}
}
doInBackground()
{
// your code
isDone = true;
}
onPostExecute() is executed on main thread, not on background thread.
I have 3 AsyncTasks and 1 ProgressBar. I want when any of task executes, the progress bar is visible and when all of them finish, the progress bar is invisible.
In Java, there is ExecutorService::isTerminated to check if all runnables finished but Android doesn't have it.
Update: 3 tasks execute at the same time.
Figure.
Nice graphic. But I am afraid there is no build in mechanism for this. You'll have to implement it by yourself. There are few solutions you could use -
Keep a reference to all 3 task. When task finishes check if the other two tasks are finished too, if yes than close the progress dialog if no wait for some other task to finish and check again. Make sure you free the references when you're done.
If you don't want to keep a reference store a counter. When the task finishes, increment the counter and check if it's equal to 3. If all tasks finished and you are done. If you implement this make sure to synchronized the access to the counter.
Try using AsyncTask.getStatus(). This works perfectly fine. Refer below sample code.
List<AsyncTask<String, String, String>> asyncTasks = new ArrayList<AsyncTask<String, String, String>>();
AsyncTask<String, String, String> asyncTask1 = new uploadTask().execute(string);
AsyncTask<String, String, String> asyncTask2 = new downloadTask().execute(string);
AsyncTask<String, String, String> asyncTask3 = new createTask().execute(string);
asyncTasks.add(asyncTask1);
asyncTasks.add(asyncTask2);
asyncTasks.add(asyncTask3);
You can later loop the AsyncTaskList and find each of the tasks' status as below.
for(int i=0;i<asyncTasks.size();i++){
AsyncTask<String, String, String> asyncTaskItem = (AsyncTask<String, String, String>)asyncTasks.get(i);
// getStatus() would return PENDING,RUNNING,FINISHED statuses
String status = asyncTaskItem.getStatus().toString();
//if status is FINISHED for all the 3 async tasks, hide the progressbar
}
A simple workaround would be to use three boolean variables one each for each AsyncTask and then check them accordingly.
A better approach would be to create a separate class that extends AsynTask and defines a callback interface which is fired in onPostExecute.
create a field to hold all tasks:
private ArrayList<HtmlDownloaderTask> mTasks;
Start your tasks this way:
HtmlDownloaderTask = new HtmlDownloaderTask(page.getHtml());
task.execute(page.getUrl());
//if you want parallel execution try this:
//task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,page.getUrl());
mTasks.add(task);
on the onPostExecute of MyAsyncTask:
int unfinishedTasks = 0;
for (HtmlDownloaderTask myDT : mTasks){
if(!(myDT.getStatus() == AsyncTask.Status.FINISHED)){
unfinishedTasks++;
}
}
if (unfinishedTasks == 1){
//We are all done. 1 Because its the current one that hasnt finished post execute
callWhateverMethod();
}
Well as you do know when an AsyncTask ends (when onPostExecute gets called):
one solution could be to create a method setProgressBarVisible() that keeps a counter and when first called sets visible, and a method setProgressBarInvisible() that decreases the counter and when zero sets the progress bar invisible.
:-? i think it's just a trick. you will return some message at onPostExecute of each Asyntask and compare it. (this message can contain a time, for example)
A official support of CompletableFuture was introduced since API level 24.
It's also available in Java 8 here.
Can use simply use something like:
taskA.thenCombine(taskB).thenCombine(taskC)
I would simply notify it at onPostExecute(), refer to onPostExecute and 4 steps in the document for detail and you can use EventBus to do some subscribe things.
This is a common question when you want to run a bunch of AsynTasks on a THREAD_POOL_EXECUTOR. It's much more faster than if you just call .execute() and all your tasks are done one by one.
So if you have multiple jobs and objects are not depending on each other states - try to run on a thread pool.
But the question is: how do I know that all of my tasks are done?
There is no built in methods in AsyncTask so you should do a little workaround.
In my case I added a static Hashmap field to my Asynctask class to keep track of all started and finished tasks. As a bonus of a map I can always know which task is currently in progress.
private static HashMap<Uri, Boolean> mapOfAttachmentTasks = new HashMap<>();
and ad simple three methods to access this map.
Important: they should be synchronized
public static synchronized void addTask(Uri uri){
mapOfAttachmentTasks.put(uri, true);
}
public static synchronized void removeTask(Uri uri){
mapOfAttachmentTasks.remove(uri);
}
public static synchronized boolean isTasksEmpty(){
return mapOfAttachmentTasks.isEmpty();
}
You want to add a new item to the tracking Map in an AsyncTask constructor and remove it in onPostExecute():
public AttachmentTask(Uri uri) {
this.uri = uri;
addTask(uri);
}
#Override
protected void onPostExecute(Attachment attachment) {
removeTask(uri);
if(isTasksEmpty())
EventBus.getDefault().post(new AttachmentsTaskFinishedEvent(attachment));
}
Everytime a task is finished it calls onPostEexecute and you check if it was the last task. If there is no tasks left - send a signal that you're done.
Now, here I used EventBus to send event to my Fragment but you can use a callback. In this case you should create an interface with callbackMethod, your Fragment (any of your UI components which are waiting for the event) should implement this interface and have that method. Then in AsyncTask constructor you get your Fragment as an argument and keep a reference to it, so you can call it's callback method when everything is done.
But I dont like such approach. First you need to keep the reference of your Fragment (or any other UI) in a WeakReference wrapper becasue you will get a memory leak when your fragment is dead (but still kept in memory becasue your AsyncTask has it's reference).
Also you would need to make a lot of checks and it will look something like that:
private boolean isAlive() {
return mFragmentWeakReference != null
&& mFragmentWeakReference.get() != null
&& mFragmentWeakReference.get().isAdded()
&& mFragmentWeakReference.get().getActivity() != null
&& !mFragmentWeakReference.get().getActivity().isFinishing();
yep, in production you should be a little paranoic and do all these checks :)
That's why you can use EventBus and if your UI is dead - whatever.
try this, maybe can help you...
final ImageUploader _upload = new ImageUploader();
_upload.setValue(getApplicationContext(), _imagepath, _urlPHP);
_upload.execute();
Runnable _run;
Handler _h2;
_run = new Runnable() {
public void run() {
_h2 = new Handler();
_h2.postDelayed(this, 1000);
Toast.makeText(getApplicationContext(), "not finished", Toast.LENGTH_LONG).show();
if (_upload.getStatus() == AsyncTask.Status.FINISHED) {
Toast.makeText(getApplicationContext(), "finished", Toast.LENGTH_LONG).show();
_h2.removeCallbacks(_run);
}
}
};
_h2 = new Handler();
_h2.postDelayed(_run, 1);
I have AsyncTask that processes some background HTTP stuff. AsyncTask runs on schedule (Alarms/service) and sometime user executes it manually.
I process records from SQLite and I noticed double-posts on server which tells me that sometime scheduled task runs and at the same time user runs it manually causing same record to be read and processed from DB twice. I remove records after they processed but still get this.
How should I handle it ? Maybe organize some kind of queing?
You can execute your AsyncTask's on an Executor using executeOnExecutor()
To make sure that the threads are running in a serial fashion please use: SERIAL_EXECUTOR.
Misc: How to use an Executor
If several activities are accessing your DB why don't create a sort of gateway database helper and use the synchronized block to ensure only one thread has access to it at an instant
Or, you can try this to see if the Task is currently running or not:
if (katitsAsyncTask.getStatus().equals(AsyncTask.Status.FINISHED))
katitsAsyncTask.execute();
else
// wait until it's done.
Initialize the AsyncTask to null. Only create a new one if it is null. In onPostExecute, set it to null again, at the end. Do the same in onCancelled, in case the user cancels this. Here's some untested code to illustrate the basic idea.
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class FooActivity extends Activity {
private class MyAsyncTask extends AsyncTask<Foo, Foo, Foo> {
#Override
protected void onPostExecute(Foo foo) {
// do stuff
mMyAsyncTask = null;
}
#Override
protected void onCancelled() {
// TODO Auto-generated method stub
mMyAsyncTask = null;
}
#Override
protected Foo doInBackground(Foo... params) {
try {
// dangerous stuff
} catch (Exception e) {
// handle. Now we know we'll hit onPostExecute()
}
return null;
}
}
private MyAsyncTask mMyAsyncTask = null;
#Override
public void onCreate(Bundle bundle) {
Button button = (Button) findViewById(R.id.b2);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mMyAsyncTask == null) {
mMyAsyncTask = new MyAsyncTask();
mMyAsyncTask.execute(null);
}
}
});
}
}
I know this was a while ago now, and you have solved your problem. but I just had a similar problem. Reno's suggestion put me on the right track, but for those who have been finding it difficult to fill in the gaps. Here is how I overcame a similar issue to that of katit's.
I wanted a particular AsyncTask to only run if it was not currently running. And as a forward from Reno's suggestion, the AsyncTask interface has been created to handle all the nitty gritty processes in properly dealing with threads for Android. Which means, the Executor is built in. As this blog suggests:
"When execute(Object.. params) is invoked on an AsyncTask the task is executed in a background thread. Depending on the platform AsyncTasks may be executed serially (pre 1.6 and potentially again in 4+), or concurrently (1.6-3.2).
To be sure of running serially or concurrently as you require, from API Level 11 onwards you can use the executeOnExecutor(Executor executor, Object.. params) method instead, and supply an executor. The platform provides two executors for convenience, accessable as AsyncTask.SERIAL_EXECUTOR and AsyncTask.THREAD_POOL_EXECUTOR respectively. "
So with this in mind, you can do thread blocking via the AsyncTask interface, it also implies you can simply use the AsyncTasks.getStatus() to handle thread blocking, as DeeV suggests on this post.
In my code, I managed this by:
Creating a global variable defined as:
private static AsyncTask<String, Integer, String> mTask = null;
And in onCreate, initialising it as an instance of my AsyncTask called CalculateSpecAndDraw:
mTask = new CalculateAndDrawSpec();
Now when ever I wish to call this AsyncTask I surround the execute with the following:
if(mTask.getStatus() == AsyncTask.Status.FINISHED){
// My AsyncTask is done and onPostExecute was called
mTask = new CalculateAndDrawSpec().execute(Integer.toString(progress));
}else if(mTask.getStatus() == AsyncTask.Status.PENDING){
mTask.execute(Integer.toString(progress));
}else{
Toast.makeText(PlaySpecActivity.this, "Please Wait..", 1000).show();
}
This spawns a new thread if it is finished, or if the thread state is PENDING, the thread is defined but has not been started we start it. But otherwise if the thread is running we don't re-run it, we simply inform the user that it is not finished, or perform what ever action we wish. Then if you wanted to schedule the next event rather than just block it from re running, take a look at this documentation on using executors.
How about just wrapping your check-what-to-send and send-it logic in a synchronized method? This approach seems to work for us.
try having some instance boolean value that gets set to "true" on the asynctask's preexecute then "false" on postexecute. Then maybe in doinbackground check if that boolean is true. if so, then call cancel on that particular duplicate task.
You could keep the state of the task in shared preferences. Check the value (Boolean perhaps) before starting the task. Set the state to finished(true?) in onPostExecute and false in onPreExecute or in the constructor
I need my Android app to periodically fetch data from a server using AJAX calls, and update the UI accordingly (just a bunch of TextViews that need to be updated with setText()). Note that this involves 2 tasks:
Making an AJAX call, and updating the UI once I receive a response - I use a simple AsyncTask for this.
Doing the above repeatedly, at regular intervals.
I haven't figured out an elegant way to achieve Point 2 above. Currently, I am simply executing the task itself from OnPostExecute(). I read on this thread at SO that I need not worry about garbage collection as far as the AsyncTask objects are concerned.
But I'm still unsure as to how I set up a timer that will fire my AsyncTask after it expires. Any pointers will be appreciated. Here is my code:
public class MyActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AjaxRequestTask().execute(MY_REST_API_URL);
}
private void updateReadings(String newReadings) {
//Update the UI
}
class AjaxRequestTask extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... restApiUrl) {
//Do AJAX Request
}
#Override
protected void onPostExecute(String result) {
updateReadings(result);
/*Is there a more elegant way to achieve this than create a new AsyncTask object every 10 seconds? Also, How can I update the UI if I create a timer here? */
new AjaxRequestTask().execute(MY_REST_API_URL);
}
}
}
Thanks in advance
EDIT:
I tried posting an answer but couldn't do it since I don't have the reputation to answer within 8 hours.
Well, so I found a solution. I'm not convinced however.
protected void onPostExecute(String result) {
updateReadings(result);
// super.onPostExecute(result);
new Timer().schedule(
new TimerTask() {
#Override
public void run() {
new AjaxRequestTask().execute(MY_REST_API_URL);
}
},
TIMER_ONE_TIME_EXECUTION_DELAY
);
}
Are there any flip sides that I should be aware of when I use this? In particular, I am seeing lots of GCs happening in the LogCat. Also, I am wondering how an AsyncTask can be candidate for GC unless the onPostExecute() completes?
How can I "stop" the updates? One way I thought of was to make the very first AsyncTask instance as a member variable of the Activity. That way, I can invoke cancel(true) on it and hope that this will "stop" the tasks.
SOLUTION:
In case anyone is looking for something similar - none of the solutions I mentioned here work satisfactorily. They all suffer from OutOfMemory issues. I did not debug into the details of the OOM, but I suspect it could either be because of the recursion, or because of having HTTP-related objects as member variables in the AsyncTask rather than as members of the Activity (basically because of NOT reusing HTTP and other objects).
I discarded this approach for a different one - making my Ajax Calls endlessly in the doInBackground() of my AsyncTask; and updating the UI in onProgressUpdate(). That way I also avoid the overhead of maintaining too many threads or Handlers for updating the UI (remember UI can be updated in onProgressUpdate() ).
This approach also eliminates the need for Timers and TimerTasks, favoring the use of Thread.sleep() instead. This thread on SO has more details and a code snippet too.
Call postDelayed() on any View to schedule a hunk of code to be run on the main application thread after a certain delay. Do this in onPostExecute() of the AsyncTask to create and execute another AsyncTask.
You could use AlarmManager, as others have cited, but I would agree with you that it feels a bit like overkill for timing that occurs purely within an activity.
That being said, if the AJAX calls should be occurring regardless of whether the activity exists, definitely consider switching to AlarmManager and an IntentService.
I think the android way to do this is using AlarmManager. Or you can user a basic java Timer as well. I'd recommend AlarmManager.
Set it up to send some intent with a custom Action, and register a broadcastreceiver for it.
If the ajax calls are only executed in the activity you can just use a timer in the activity which starts the tasks.
Otherwise use a service which uses the AlarmManager and which connects to the gui via a broadcast.
The recommended way to do a repeated task, is via AlarmManager, as alluded to by Scythe. Basically it involves setting up a broadcast listener, and having AlarmManager fire off an intent to that listener at whatever interval you choose. You then would have your broadcast listener call out to the activity to run the AsyncTask. If you need a very tight timer (less than 5s calls I'd say), then you're better off using a Timer within a Service, and using AIDL to call back to the activity.
Instead of talking directly from the broadcast intent, you could also setup an IntentService which you can poke, and use AIDL to update the activity.
This is how I achieved it finally. Note that the AsyncTask cancel(true) method is useless in my scenario because of the recursion. I used what #CommonsWare suggested - used a flag to indicate whether any more tasks should be executed.
public class MyActivity extends Activity {
/*Flag which indicates whether the execution should be halted or not.*/
private boolean mCancelFlag = false;
private AjaxRequestTask mAjaxTask;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(mAjaxTask == null){
mAjaxTask = new AjaxRequestTask();
}
mAjaxTask.execute(MY_REST_API_URL);
}
#Override
protected void onResume() {
super.onResume();
mCancelFlag = false; /*when we resume, we want the tasks to restart. Unset cancel flag*/
/* If the main task is Finished, create a new task and execute it.*/
if(mAjaxTask == null || mAjaxTask.getStatus().equals(AsyncTask.Status.FINISHED)){
new AjaxRequestTask().execute(TLS_REST_API_URL);
}
}
#Override
protected void onPause() {
mCancelFlag = true; /*We want the execution to stop on pause. Set the cancel flag to true*/
super.onPause();
}
#Override
protected void onDestroy() {
mCancelFlag = true;/*We want the execution to stop on destroy. Set the cancel flag to true*/
super.onDestroy();
}
private void updateReadings(String result) {
//Update the UI using the new readings.
}
class AjaxRequestTask extends AsyncTask<String, Integer, String> {
private AjaxRequestTask mChainAjaxRequest;
private Timer mTimer;
private TimerTask mTimerTask;
#Override
protected String doInBackground(String... restApiUrl) {
//Do AJAX call and get the response
return ajaxResponse;
}
#Override
protected void onPostExecute(String result) {
Log.d(TAG, "Updating readings");
updateReadings(result);
// super.onPostExecute(result);
if(mTimer == null){
mTimer = new Timer();
}
if(!mCancelFlag){/*Check if the task has been cancelled prior to creating a new TimerTask*/
if(mTimerTask == null){
mTimerTask = new TimerTask() {
#Override
public void run() {
if(!mCancelFlag){/*One additional level of checking*/
if(mChainAjaxRequest == null){
mChainAjaxRequest = new AjaxRequestTask();
}
mChainAjaxRequest.execute(MY_REST_API_URL);
}
}
};
}
mTimer.schedule(mTimerTask,TIMER_ONE_TIME_EXECUTION_DELAY);
}
}
}
}