Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AsyncTask equivalent in java

In android there is the AsyncTask which runs a thread and then i can use the method on post execute to interact with main thread again. is there an equivalent to this in java? i am trying to run a timer on separate thread (doInBackground) and once the time is finished it will then allow me to interact with the main theard to restart a service (onPostExecute will restart service)

like image 256
Jdavis649 Avatar asked Mar 28 '16 23:03

Jdavis649


2 Answers

I'm not Android developer but I think it could be easily implemented by using a CompletableFuture on Java 8:

import java.lang.reflect.InvocationTargetException;
import java.util.concurrent.CompletableFuture;
import javax.swing.SwingUtilities;

public abstract class AsyncTask <Params, Progress, Result> {
    protected AsyncTask() {
    }

    protected abstract void onPreExecute();

    protected abstract Result doInBackground(Params... params) ;

    protected abstract void onProgressUpdate(Progress... progress) ;

    protected abstract void onPostExecute(Result result) ;

    final void  publishProgress(Progress... values) {
        SwingUtilities.invokeLater(() -> this.onProgressUpdate(values) );
    }

    final AsyncTask<Params, Progress, Result> execute(Params... params) {
        // Invoke pre execute
        try {
            SwingUtilities.invokeAndWait( this::onPreExecute );
        } catch (InvocationTargetException|InterruptedException e){
            e.printStackTrace();
        }

        // Invoke doInBackground
        CompletableFuture<Result> cf =  CompletableFuture.supplyAsync( () -> doInBackground(params) );

        // Invoke post execute
        cf.thenAccept(this::onPostExecute);
        return this;
    }
}
like image 198
Tuan Do Avatar answered Sep 25 '22 08:09

Tuan Do


Solution Tailored for You

In short, look at java: run a function after a specific number of seconds.

For your purpose, you don't need an AsyncTask. AsyncTask is for running something that needs the time, but you would prefer it didn't (e.g. a complex calculation or fetching data from the internet). It's for getting around the problem that you would need to wait.
What you want to do instead is to introduce a delay, or more precisely you want to schedule some action to happen after a delay. You can use a class like AsyncTask for this as well, but it's an overkill and results in more complicated code. You should instead use a class which is tailored for delayed execution, which is Timer and TimerTask:

new java.util.Timer().schedule(
        new java.util.TimerTask() {
            @Override
            public void run() {
                // your code here
            }
        },
        5000
);

Equivalent of AsyncTask in standard Java

Note that AsyncTask is connected to a UI concept (UI = user interface), because it may only be started from the UI thread. It's not for generally running something asynchronously.

Thus, the best matching equivalent of android's AsyncTask is SwingWorker in Java. Swing is Java's standard UI framework. It has a similar concept as android with a UI thread. In Swing, this thread is called the Event Dispatch Thread. Hence, the design of SwingWorker is also very similar to AsyncTask. Even the doInBackground() method has the same name in both classes.

Asynchronous Execution in General

If your requirement is not related to a UI and you only want to source some time consuming operation out so it executes asynchronously, then you need to look at executors. There is a variety of different ways to use executors for many different purposes, so this would go beyond the scope of this answer. If you are interested in further information, start with Jakob Jenkov's tutorial on ExecutorService.

like image 21
Daniel S. Avatar answered Sep 23 '22 08:09

Daniel S.