SkillAgentSearch skills...

AsyncJobLibrary

Android library to easily queue background and UI tasks

Install / Use

/learn @jmartinesp/AsyncJobLibrary
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

AsyncJobLibrary

Android library to easily queue background and UI tasks

Index

Why AsyncJob?

In my latest projects I started using Android Annotations, which has an amazing set of tools to make creating Android applications a lot easier.

However, for some stuff I wanted to make having to inherit from auto-built classes was an impossible thing to do and I ended up having half of my project using AndroidAnnotations and the other half doing stuff manually.

So I thought: maybe I should try ButterKnife instead. That worked better, I could inject views whenever I wanted and I still had some of the "@Click" stuff I liked.

But not everything was good. AndroidAnnotations had a pair of annotations called @Background and @UIThread which magically -well, not so magically- allowed your code to be executed on the UI Thread or on a Background one with no effort. I REALLY missed those annotations as they allowed me to have a way cleaner code, so I started thinking how could I replace them.

AsyncJob was the closest I got to that.

So what does it exactly do?

If you are working on Android you probably have ended up using AsyncTasks to do background tasks and then have a response on the UI Thread. Well, I'll confess: I HATE ASYNCTASKS.

I don't see why I would need to extend a class EVERY FUCKING TIME I want to do some work on background. Also, having to create a Thread and a Handler EVERY FUCKING TIME I wanted to do some background work and have a response wasn't a good option.

So what I did was to create a library which does that for you.

How does it work?

It's really easy. If you want the library to work in a similar way to AsyncTask, you can create an AsyncJob<JobResult> where JobResult is the type or class of the item it will return.

But creating an AsyncJob was also a boring thing to do so I created an AsyncJobBuilder<T> which allows you to create AsyncJobs in a fast and clean way.

AsyncJobs have two interfaces which will be used to store your code and execute it on backgrund or on the main thread. These are AsyncAction<ActionResult> and AsyncResultAction<ActionResult>. They can be set by:

asyncJob.setActionInBackground(actionInBackground);
asyncJob.setActionOnResult(actionOnMainThread);

And when you use asyncJob.start() it will call those interfaces and execute your code.

Here you have an example of an AsyncJob created by an AsyncJobBuilder:

new AsyncJob.AsyncJobBuilder<Boolean>()
        .doInBackground(new AsyncJob.AsyncAction<Boolean>() {
            @Override
            public Boolean doAsync() {
                // Do some background work
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                return true;
            }
        })
        .doWhenFinished(new AsyncJob.AsyncResultAction<Boolean>() {
            @Override
            public void onResult(Boolean result) {
                Toast.makeText(context, "Result was: " + result, Toast.LENGTH_SHORT).show();
        }
}).create().start();

Using static methods

Most of the time, though, I will prefer doing the following:

  • Execute some code in background.
  • Execute some code on the UI thread from that background thread whenever I have to, not just to return a value.

So how do yo do that?

You use the provided static methods, AsyncJob.doInBackground() and AsyncJob.doOnMainThread():

AsyncJob.doInBackground(new AsyncJob.OnBackgroundJob() {
    @Override
    public void doOnBackground() {

        // Pretend it's doing some background processing
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Create a fake result (MUST be final)
        final boolean result = true;

        // Send the result to the UI thread and show it on a Toast
        AsyncJob.doOnMainThread(new AsyncJob.OnMainThreadJob() {
            @Override
            public void doInUIThread() {
                Toast.makeText(context, "Result was: "+ result, Toast.LENGTH_SHORT).show();
            }
        });
    }
});

Which also have some interfaces made specially for them.

That's good, but I'd like to have a better control of my background threads!

Well, you can. You can provide an ExecutorService to an AsyncJob and the tasks that you want will be queued to it:

// Create a job to run on background
AsyncJob.OnBackgroundJob job = new AsyncJob.OnBackgroundJob() {
    @Override
    public void doOnBackground() {
        // Pretend to do some background processing
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // This toast should show a difference of 1000ms between calls
        AsyncJob.doOnMainThread(new AsyncJob.OnMainThreadJob() {
            @Override
            public void doInUIThread() {
                Toast.makeText(context, "Finished on: "+System.currentTimeMillis(), Toast.LENGTH_SHORT).show();
            }
        });
    }
};

// This ExecutorService will run only a thread at a time
ExecutorService executorService = Executors.newSingleThreadExecutor();

// Send 5 jobs to queue which will be executed one at a time
for(int i = 0; i < 5; i++) {
    AsyncJob.doInBackground(job, executorService);
}

In this example, I am supplying a SingleThreadExecutor to the AsyncJob, which will only allow one thread to run at a time, serializing their execution. You can provide any other ExecutorServices tof it your needs.

How do I add it to my project?

Add it to your gradle dependencies like this:

dependencies {
    ...
    compile 'com.arasthel:asyncjob-library:1.0.3'
    ...
}

Also, you can manually download or clone this repo and import it to your current project as a Module.

Reference:

Interfaces:

// These are for AsyncJob objects
public interface AsyncAction<ActionResult> {
    public ActionResult doAsync();
}
public interface AsyncResultAction<ActionResult> {
    public void onResult(ActionResult result);
}

// These are for the static methods
public interface OnMainThreadJob {
    public void doInUIThread();
}
public interface OnBackgroundJob {
    public void doOnBackground();
}

AsyncJob static methods:

/**
 * Executes the provided code immediately on a background thread
 * @param onBackgroundJob Interface that wraps the code to execute
 */
public static void doInBackground(OnBackgroundJob onBackgroundJob);

/**
 * Executes the provided code immediately on the UI Thread
 * @param onMainThreadJob Interface that wraps the code to execute
 */
public static void doOnMainThread(final OnMainThreadJob onMainThreadJob);

/**
 * Executes the provided code immediately on a background thread that will be submitted to the
 * provided ExecutorService
 * @param onBackgroundJob Interface that wraps the code to execute
 * @param executor Will queue the provided code
 */
public static FutureTask doInBackground(final OnBackgroundJob onBackgroundJob, ExecutorService executor);

AsyncJob object methods:

public AsyncJob<JobResult>();
// Sets the action to execute on background
public void setActionInBackground(AsyncAction actionInBackground);
public AsyncAction getActionInBackground();

// Sets an action to be executed when the background one ends and returns a result
public void setActionOnResult(AsyncResultAction actionOnMainThread);
public AsyncResultAction getActionOnResult();

// Sets the optional ExecutorService to queue the jobs
public void setExecutorService(ExecutorService executorService);
public ExecutorService getExecutorService();

// Cancels the AsyncJob interrupting the inner thread.
public void cancel();

// Starts the execution
public void start();

AsyncJobBuilder methods:

public AsyncJobBuilder<JobResult>();

/**
 * Specifies which action to run on background
 * @param action the AsyncAction to run
 * @return the builder object
 */
public AsyncJobBuilder<JobResult> doInBackground(AsyncAction<JobResult> action);

/**
 * Specifies which action to run when the background action ends
 * @param action the AsyncAction to run
 * @return the builder object
 */
public AsyncJobBuilder<JobResult> doWhenFinished(AsyncResultAction action);

/**
 * Used to provide an ExecutorService to launch the AsyncActions
 * @param executor the ExecutorService which will queue the actions
 * @return the builder object
 */
public AsyncJobBuilder<JobResult> withExecutor(ExecutorService executor);

/**
 * Instantiates a new AsyncJob of the given type
 * @return a configured AsyncJob instance
 */
public AsyncJob<JobResult> create();

License

This software is licensed under Apachev2 which basically means that you can make your own version and it can be private.

Here is a small summary of the license:

Copyright 2014 Jorge Martín Espinosa (Arasthel)

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the Licens
View on GitHub
GitHub Stars222
CategoryDevelopment
Updated2mo ago
Forks44

Languages

Java

Security Score

95/100

Audited on Jan 19, 2026

No findings