Can I chain async task sequentially (starting one after the previous asynctask completes)
I also had some same situation the other day.
I had solved it in this way:
Pass the reference of your activity to the constructor of async class and execute the do in background function. Now in post execute function call a public method of ur activity from async class to execute the task again... or try this:
if (asynclass.getStatus() == android.os.AsyncTask.Status.PENDING) {
asynclass.execute();
} else if (RF.getStatus() == android.os.AsyncTask.Status.FINISHED) {
asynclass = new asyncclass();
asynclass.execute();
} else {
Toast.maketoast(this, "Plz wait", 1).show();
}
Cheers
Execute two sequences of AsyncTasks serially
A simple queue will work for now:
public class OperationsQueue {
private Operation ongoingOperation;
private Queue<Operation> queue = new LinkedList<>();
public void execute(Operation operation) {
if (ongoingOperation != null)
queue.add(operation);
else {
ongoingOperation = operation;
operation.setOnFinishedCallback(() -> operationFinished(operation));
operation.execute();
}
}
private void operationFinished(Operation operation) {
ongoingOperation = null;
Operation nextOperation = queue.poll();
if (nextOperation != null)
execute(nextOperation);
}
}
public abstract class Operation {
protected Runnable onFinished = () -> { };
public abstract void execute();
public void setOnFinishedCallback(Runnable onFinished) {
this.onFinished = onFinished;
}
}
Concrete implementations of Operation
need to start the first async task in the sequence and the last async task must call onFinished.
That is in case of this sequence:
A -> B
An operation passes a callback to async task A
which it passes to async tasks it starts so that the last task B
calls it in its onPostExecute
:
class SomeOperation extends Operation {
public void execute() {
new A(() -> onFinished()).execute();
}
}
class A extends AsyncTask<Void, Void, Void> {
//...
public Runnable onSuccess;
public A(Runnable onSuccess) {
this.onSuccess = onSuccess;
}
onPostExecute() {
new B(onSuccess).execute();
}
}
class B extends AsyncTask<Void, Void, Void> {
//...
public Runnable onSuccess;
public B(Runnable onSuccess) {
this.onSuccess = onSuccess;
}
onPostExecute() {
onSuccess.run();
}
}
SomeOperation
and its underlying tasks may now be executed serially:
OperationsQueue queue = new OperationsQueue();
queue.execute(new SomeOperation());
queue.execute(new SomeOperation());
Task A
of the second SomeOperation
will not execute until task B
on the first finishes.
Is chaining AsyncTasks considered bad practice?
You can definitely do that and there is nothing wrong with chaining multiple AsyncTasks
if you really have to. And I want to emphasise: only if you really have to.
AsyncTasks
bring a certain overhead with them. If you chain two AsyncTasks
you get twice the overhead. You don't want that. You should use the least amount of AsyncTasks
possible.
In your case the solution actually seems quite simple: Perform all of the work in just one AsyncTask
. Ask yourself: Is there really any need for two separate AsyncTasks
? From your description it certainly doesn't seem like it. If you just use one AsyncTask
your code will run a lot more efficiently than if you use two.
Please note that AsyncTasks
should only be used for short operations that take a few seconds and which are started in response to a user action. If you need to perform some long running operation in the background than an AsyncTask
is probably not the best solution. I can't really tell from your description if what you want to do is something suited for an AsyncTask
or not, but if the work you are doing doesn't fall into the criteria I described above you are probably better of with an alternative solution.
Design pattern for modular AsyncTask in Android
Multiple AsyncTask can be run in serial or parallel way by using executeOnExecutor
with parameter AsyncTask.SERIAL_EXECUTOR
or AsyncTask.THREAD_POOL_EXECUTOR
.
If you expect a result with a wait mechanism(e.g wait for a task to finish and return a result) then the better way is to use Future. One such implementation is FutureTask which relies on Callable like this:
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
FutureTask<String> future = new FutureTask(new Callable() {
public String call() {
...
return res;
});
executor.execute(future);
String res = future.get();
The last line will block the operation until Callable inside returns its String result. In fact you can even set a timeout for it to finish.
Remember that AsyncTask doesn't only perform asynchronous operation. It also carries out its process on background thread. So you may still use an AsyncTask (or Thread) to do synchronous operations which otherwise would block the UI.
Android calling AsyncTask right after an another finished
you can use getStatus()
checks whether the the AsyncTask
is pending, running, or finished.and when finsh start your new task.like:
if(authTask .getStatus() == AsyncTask.Status.PENDING){
// My AsyncTask has not started yet
}
if(authTask .getStatus() == AsyncTask.Status.RUNNING){
// My AsyncTask is currently doing work in doInBackground()
}
if(authTask .getStatus() == AsyncTask.Status.FINISHED){
// START NEW TASK HERE
}
example for your app:
btn.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
if (authTask != null && authTask.getStatus() == AsyncTask.Status.FINISHED) {
//START YOUR NEW TASK HERE
}
else
{
//IGNORE BUTTON CLICK
}
}
});
Execute Code only after async task complete
Create a callback in GetBitMapFromURL.
public class GetBitMapFromURL extends AsyncTask<Void, Void, Void> {
private GetBitMapFromURLCallback mCallback = null;
public WebService(GetBitMapFromURLCallback callback) {
mCallback = callback;
}
@Override
protected Boolean doInBackground(Void... params) {
// ...
}
@Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if (mCallback != null) {
mCallback.onGetBitMapFromURLComplete(this);
}
}
public interface GetBitMapFromURLCallback {
public void onGetBitMapFromURLComplete(GetBitMapFromURL getBitMapFromUrl);
}
}
public class MyActivity extends Activity implements GetBitMapFromURLCallback {
// ...
public void onGetBitMapFromURLComplete(GetBitMapFromURL getBitMapFromUrl) {
// This code will get called the moment the AsyncTask finishes
}
}
And let your activity implements this callback and onGetBitMapFromURLComplete()
.
AsyncTask with Timer keeps on running
Following links can helps you, please have a look, Thanks.
Android: Can I chain Async task sequentially (starting one after the previous asynctask completes)
and
Android calling AsyncTask right after an another finished
How to Sequentially execute Asynctask in a Loop?
Simplest option: only have one AsyncTask
, where you process all the work in a single doInBackground()
, using publishProgress()
and onProgressUpdate()
to publish per-download results, if needed. I do not know why you think having N non-parallel AsyncTask
instances is a good idea.
Or: don't use AsyncTask
at all. Use your own ThreadPoolExecutor
, so you have complete control over the characteristics of your jobs. Use an event bus (greenrobot's EventBus, Otto, LocalBroadcastManager
, etc.) to publish the results on the UI thread.
Or: From onPostExecute()
of the first AsyncTask
, start the next AsyncTask
in your chain.
Related Topics
Tcp\Ip Client - Ehostunreach (No Route to Host)
Android: Google Maps API - Change Position of Maps Toolbar
How to Apply Custom Filters in a Camera [Surfaceview Preview]...
Driver Jdbc Postgresql with Android
Getting Wrong Month When Using Simpledateformat.Parse
Online Radio Streaming App for Android
Android: Specify Two Different Images for Togglebutton Using Xml
What Does Transitive = True in Gradle Exactly Do (W.R.T. Crashlytics)
Android App Bundle Introduces Resource Not Found Crash in Android App
How to Show Ellipses on My Textview If It Is Greater Than the 1 Line
How to Simulate Low Memory in the Android Emulator
Httpurlconnection.Getresponsecode() Returns -1 on Second Invocation