AsyncJobLibrary


Source link: https://github.com/Arasthel/AsyncJobLibrary

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 License at

http://www.apache.org/licenses/LICENSE-2.0  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.  

About me:

I'm a freelance Android developer which can also code some Objective-C, Swift and little web (RoR, Django, even some NodeJS...). You can find more about me here. Bad thing is: I'm Spanish and I mostly speak Spanish on those sites. Anyway, you can contact me writing in English if you need help or want to talk.

Resources

IncDec library will allow you to perform increment and decrement operation. As it supports single click and long press, it enhances UX solving the delay problem in the typical number picker.

Download manager via okhttp.

This is amazing android library to add tab-digits with an old -fashion transition as old clock does.

Cinder helps you write concise and declarative code with Android’s data binding Observable classes.

Perm is a library that makes it simple to check and request Android Permissions at runtime (like Camera or GPS) for Apps targeting Android 6 or more.

Simple Android library which filters Logs, for example by keeping only ERROR Logs in RELEASE mode.

Topics


2D Engines   3D Engines   9-Patch   Action Bars   Activities   ADB   Advertisements   Analytics   Animations   ANR   AOP   API   APK   APT   Architecture   Audio   Autocomplete   Background Processing   Backward Compatibility   Badges   Bar Codes   Benchmarking   Bitmaps   Bluetooth   Blur Effects   Bread Crumbs   BRMS   Browser Extensions   Build Systems   Bundles   Buttons   Caching   Camera   Canvas   Cards   Carousels   Changelog   Checkboxes   Cloud Storages   Color Analysis   Color Pickers   Colors   Comet/Push   Compass Sensors   Conferences   Content Providers   Continuous Integration   Crash Reports   Credit Cards   Credits   CSV   Curl/Flip   Data Binding   Data Generators   Data Structures   Database   Database Browsers   Date &   Debugging   Decompilers   Deep Links   Dependency Injections   Design   Design Patterns   Dex   Dialogs   Distributed Computing   Distribution Platforms   Download Managers   Drawables   Emoji   Emulators   EPUB   Equalizers &   Event Buses   Exception Handling   Face Recognition   Feedback &   File System   File/Directory   Fingerprint   Floating Action   Fonts   Forms   Fragments   FRP   FSM   Functional Programming   Gamepads   Games   Geocaching   Gestures   GIF   Glow Pad   Gradle Plugins   Graphics   Grid Views   Highlighting   HTML   HTTP Mocking   Icons   IDE   IDE Plugins   Image Croppers   Image Loaders   Image Pickers   Image Processing   Image Views   Instrumentation   Intents   Job Schedulers   JSON   Keyboard   Kotlin   Layouts   Library Demos   List View   List Views   Localization   Location   Lock Patterns   Logcat   Logging   Mails   Maps   Markdown   Mathematics   Maven Plugins   MBaaS   Media   Menus   Messaging   MIME   Mobile Web   Native Image   Navigation   NDK   Networking   NFC   NoSQL   Number Pickers   OAuth   Object Mocking   OCR Engines   OpenGL   ORM   Other Pickers   Parallax List   Parcelables   Particle Systems   Password Inputs   PDF   Permissions   Physics Engines   Platforms   Plugin Frameworks   Preferences   Progress Indicators   ProGuard   Properties   Protocol Buffer   Pull To   Purchases   Push/Pull   QR Codes   Quick Return   Radio Buttons   Range Bars   Ratings   Recycler Views   Resources   REST   Ripple Effects   RSS   Screenshots   Scripting   Scroll Views   SDK   Search Inputs   Security   Sensors   Services   Showcase Views   Signatures   Sliding Panels   Snackbars   SOAP   Social Networks   Spannable   Spinners   Splash Screens   SSH   Static Analysis   Status Bars   Styling   SVG   System   Tags   Task Managers   TDD &   Template Engines   Testing   Testing Tools   Text Formatting   Text Views   Text Watchers   Text-to   Toasts   Toolkits For   Tools   Tooltips   Trainings   TV   Twitter   Updaters   USB   User Stories   Utils   Validation   Video   View Adapters   View Pagers   Views   Watch Face   Wearable Data   Wearables   Weather   Web Tools   Web Views   WebRTC   WebSockets   Wheel Widgets   Wi-Fi   Widgets   Windows   Wizards   XML   XMPP   YAML   ZIP Codes