Corleone
Java annotation processor library used to dispatch and concatenate background tasks in a decoupled way through a simple syntax.
Usage
The use of the library is pretty simple. First of all, you will need to know about the available annotations.
Annotations
@Job
: Used on top of your background task classes, it can contain multiple annotations of type@Rule
.@Rule
: Every job can have multiple Rules. A@Rule
is used to define an execution context for the job, and an optionalpreviousJob
class (For concatenation).@Param
: Used on job class attribute fields to allow param injection through autogenerated param binders. As the responsibily of building job instances will reside on the library, job class constructors will not be allowed. Params will satisfy their corresponding runtime values when the job gets instantiated by Corleone. Keep reading to know how to provide them.@Execution
: Used to annotate a job method. Only one method can be flagged as the@Execution
method for a class. This will be the method containning the background logic, as it will be the one executed automatically by Corleone at the right moment.
Jobs
Corleone loves to delegate all the dirty jobs on his beloved family members to avoid worries. @Job
syntax will be like:
@Job({
@Rule(context = "ObtainGames", previousJob = CheckNetworkConnection.class)
}
) public class GetGamesFromService {
@Param("RestRepo") GameRepository restGameRepository;
@Param("PageNum") int pageNumber;
@Param("RestCallback") Callback callback;
@Execution
public void run() {
try {
List<Game> games = gameRepository.obtainGamesByPage(pageNumber);
notifyGamesLoaded(games);
}
catch (ObtainGamesException exception) {
notifyPetitionError(exception.getMessage());
}
}
private void notifyGamesLoaded(final List<Game> games) {
callback.onGamePageLoaded(games);
Corleone.context("ObtainGames").provideParam("games", games);
Corleone.context("ObtainGames").keepGoing();
}
private void notifyPetitionError(final String message) {
callback.onGettingGamesError(message);
}
}
You can declare as many jobs as you want and link them by @Rule
contexts.
Job dispatch
To start the job chain dispatch, this will be your code:
Corleone.context("ObtainGames").dispatchJobs();
Param providing
As you can see in the previous code snippet, @Job
params are given by some kind of injection technique. You don't pass them as method or constructor arguments, but provide them by two different ways. The first one is into the @Job
dispatch call arguments.
JobParams jobParams = new JobParams()
.append("ConnectivityManager", connectivityManager);
.append("RestRepo", restGameRepository)
.append("PersistenceRepo", persistenceGameRepository)
.append("PageNum", pageNumber)
.append("RestCallback", getRestGameQueryCallback())
.append("PersistenceCallback", getPersistenceGameQueryCallback());
Corleone.context("ObtainGames").dispatchJobs(jobParams);
This example shows how to provide params for the whole @Job
context execution. All the jobs linked to that context will be able to use them. This is the right way to provide params just before starting the job chain execution. The append()
method requires a param qualifier and a param value.
The second way available is being used in the GetGamesFromService
job code snippet:
Corleone.context("ObtainGames").provideParam("MyParamQualifier", paramValue);
Params can be added by provideParam()
method too. This method can be used to provide params from one @Job
to another that will be executed later on. Sometimes we need to use the output results from one task as the input ones for a new one. This would be the right way to do so.
Multiple context calls
You can provide params and keep the queue going by using the allContexts(this)
method versions from inside a @Job
:
Corleone.allContexts(this).provideParam("MyParamQualifier", myParamValue);
Corleone.allContexts(this).keepGoing();
If you do that, the method will be executed for all the contexts declared for the current job into its @Rule
annotations.
Dependencies
- AutoService: Annotation processor from Google auto library module. A metadata/config generator to avoid typical ServiceLoader manual setup.
- JavaPoet: A Square's java source file generation library (Successor of JavaWriter).
Testing
- Compile-testing: Google testing framework to allow testing java sources @ javac compile time.
- Truth: Google library to "humanize" language level of JUnit testing assertions.
- JUnit4: Base for all the project unit tests.
Gradle dependency
Since the project is still a snapshot, you will need to add the following repositories to your project to get the dependency resolved.
repositories {
mavenCentral()
maven {
url "https://oss.sonatype.org/content/repositories/snapshots"
}
}
dependencies{
compile 'com.github.jorgecastilloprz:corleone:0.2-SNAPSHOT'
provided 'com.github.jorgecastilloprz:corleone-compiler:0.2-SNAPSHOT'
}
You will need to add this Lint rule in your build.gradle.
lintOptions {
disable 'InvalidPackage'
}
Some configurations may also require additional exclusions.
packagingOptions {
exclude 'META-INF/services/javax.annotation.processing.Processor'
}
Maven dependency
<dependency>
<groupId>com.github.jorgecastilloprz</groupId>
<artifactId>corleone</artifactId>
<version>0.2-SNAPSHOT</version> </dependency> <dependency>
<groupId>com.github.jorgecastilloprz</groupId>
<artifactId>corleone-compiler</artifactId>
<version>0.2-SNAPSHOT</version> </dependency>
TODO
- Add caching strategy to survive Android stupid lifecycle logic (Screen rotation etc).
- Add dagger injection support.
Attributions
- Processor code inspired by projects butterknife, icepick, and some others.
- Annotation processor logic and basic techniques inspired by hannesdorfmann.com APT blog post too.
- Some of the sample app code has been inspired by @antoniolg MaterializeYourApp sample application.
Developed By
- Jorge Castillo Pérez - [email protected]
License
Copyright 2015 Jorge Castillo PĂ©rez 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.