Skip to content

Repository files navigation

AxoloTL

Axolo Task Library

Dependencies (from jitpack)

compile "com.github.AutSoft.AxoloTL:compiler-core:${axolotlVersion}"
compile "com.github.AutSoft.AxoloTL:tasklib:${axolotlVersion}"
compile "com.github.AutSoft.AxoloTL:tasklib-core:${axolotlVersion}"
compile "com.github.AutSoft.AxoloTL:tasklib-stetho:${axolotlVersion}"
testCompile "com.github.AutSoft.AxoloTL:tasklib-test:${axolotlVersion}"
annotationProcessor "com.github.AutSoft.AxoloTL:taskcompiler:${axolotlVersion}"

Task creation

  • Create a *Worker class
  • Create a function in the Worker class with synchronous code
  • Use @CreateTask annotation for the function
  • TaskLib compiler will create a Task for every function annotated with @CreateTask
    • Every task class has the same parameters for the constructor as in the function which represented by the class
    • The getResult() function has the same return type as the function
publicclassSimpleWorker {
@CreateTaskpublicStringfirst(intparameter) {
return"Result: " + parameter;
}
}

Task usage

  • Create a TaskEngineHolder where you would like to use the task (inside in an activity, fragment, etc.)
  • Execute the task with the executeTask function of the TaskEngineHolder
publicclassSampleTaskFragmentextendsFragment {
TaskEngineHolderholder;
publicSampleTaskFragment() {
holder = newTaskEngineHolder(this);
}
@OverridepublicvoidonResume() {
super.onResume();
holder.start();
holder.executeTask(newFirstTask(3));
}
@OverridepublicvoidonPause() {
super.onPause();
holder.stop();
}
publicvoidonTaskResult(FirstTasktask) {
if(!task.hasError()) {
// Handle resultStringresult = task.getResult();
} else {
// Handle error...
}
}
}

For MVP, sample presenter:

publicabstractclassPresenter<S> {
protectedSscreen;
privateTaskEngineHolderholder = newTaskEngineHolder(this);
@CallSuperpublicvoidattachScreen(Sscreen) {
this.screen = screen;
holder.start();
}
@CallSuperpublicvoiddetachScreen() {
this.screen = null;
holder.stop();
}
publicvoidstartFirstTask() {
holder.executeTask(newFirstTask);
}
publicvoidonTaskResult(FirstTasktask) {
if(!task.hasError()) {
// Handle resultStringresult = task.getResult();
} else {
// Handle error...
}
}
}

Inline 'callbacks'

holder.executeTask(newFirstTask(3), , newInlineTaskListener<String, Void>() {
@OverridepublicvoidonTaskResult(BaseTask<String, Void> task) {
// handle task result...
}
});

Error: Task Exception

In the worker function you can throw any RuntimeException. If any exception thrown, then the task.hasError() function will return true. With the task.getException() function you can get the thrown exception in the task result function.

Function in worker:

@CreateTaskpublicvoidtaskWithError() {
thrownewTaskException(ERROR_CODE_INTEGER);
}

Callback:

publicvoidonTaskResult(TaskWithErrorTasktask) {
task.hasError(); // returns truetask.getErrorCode(); // returns ERROR_CODE_INTEGER
}

Error Object

You can pass any error object with the TaskException:

@CreateTaskpublicvoidtaskWithError() {
thrownewTaskException(ERROR_CODE_INTEGER, newCustomObject());
}

In the callback function use getErrorObject() function:

publicvoidonTaskResult(TaskWithErrorTasktask) {
task.hasError(); // returns truetask.getErrorCode(); // returns ERROR_CODE_INTEGERtask.getErrorObject(); // returns the created CustomObject
}

Progress

In the worker function you can use a TaskAgent as a first argument (it is only allowed in the first place). With a TaskAgent instance (which is created and passed by the Task Library) you can send progress updates to the caller.

publicclassProgressWorker {
@CreateTaskpublicStringlongRunning(TaskAgent<String> agent, intparameter) {
intmax = 10;
for (inti = 0; i < max; i++) {
intpercent = (int) ((100.0 * i) / max);
agent.publishProgress("PROGRESS: " + percent + "%");
Thread.sleep(300); // some long-running synch work
}
agent.publishProgress("PROGRESS: 100%");
return"DONE: " + parameter;
}
}

In the target object you can define an onTaskProgress function with two argument. One for the task and one for the progress object:

protectedvoidonTaskProgress(LongRunningTasktask, Stringprogress) {
// setProgress("onTaskProgress: " + progress);
}

Global Task Exception

Global task exception is similar to the simple task exception. The main difference is that you can handle global errors in any target which is held by a TaskEngineHolder:

publicbooleanonTaskGlobalError(GlobalErrorerror) {
if (error.getErrorCode() == SOME_CODE) {
// handle global errorreturntrue;
}
returnfalse;
}

TaskLib try to call the onTaskGlobalError method in the target which is executed the task with global error. If it is unsuccessful or the error is not handled then it will call the other targets in unspecified order. If any onTaskGlobalError method returns true then the global error is handled and there won't be any effect of the execution of the task (no onTaskResult or other call). If non of the onTaskGlobalError method returns true then the global task exception is handled like it was a simple task exception (onTaskResult call with hasError and errorCode).

Follow Task

FIXME

Defining a scheduler for a task

The @CreateTask annotation has a value parameter to specify which scheduler you want to use for running the task.

public class CustomSchedulersWorker {
@CreateTask(TaskSchedulers.IO)
public void customSchedulerIo() {
// do some work...
}
@CreateTask(MyCustomSchedulers.MY_SCHEDULER)
public void fullCustomScheduler() {
// do some work...
}
}

In TaskSchedulers there are some basic scheduler which comes from RxJava:

  • SINGLE
  • COMPUTATION
  • IO
  • TRAMPOLINE
  • NEW_THREAD

If you need a custom scheduler you can register it with a positive integer id and you can use this id in @CreateTask annotation.

TaskSchedulers.registerScheduler(MyCustomSchedulers.MY_SCHEDULER, Schedulers.newThread());

Dagger compatibility

For dagger injection you have to annotate your injector static instance with hu.axolotl.tasklib.annotation.Injector annotation.

@InjectorpublicstaticAppComponentinjector;

In the AppComponent interface you have to declare a new method for the helpers of each worker. For example if you have a ProfileWorker then the lib will generate a ProfileWorkerTaskHelper class, so you have to add:

voidinject(FriendsWorkerTaskHelperfriendsWorkerTaskHelper);

Rx support

publicclassRxTasksWorker {
@CreateTaskpublicFlowable<String> flowable() {
returnFlowable.just("Flowable done!");
}
@CreateTaskpublicObservable<String> observable() {
returnObservable.just("Observable done!");
}
@CreateTaskpublicSingle<String> single() {
returnSingle.just("Single done!");
}
@CreateTaskpublicCompletablecompletable() {
returnCompletable.complete();
}
}

Stetho support

FIXME

Testing

FIXME

Matcher

FIXME

Util

Compiler-Core

Future plans

  • Foreground service support for workers: So you can use executeTask to start a foreground service with given icon, name, etc.

License

Copyright 2017 AutSoft Kft.
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

Axolo Task Library

Resources

Stars

5 stars

Watchers

4 watching

Forks

Releases

Packages

Contributors

Languages