- Notifications
You must be signed in to change notification settings - Fork1
Android library for building pipelines for executing background tasks
License
udeyrishi/pipe
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Pipe is an Android library for building pipelines for executing background tasks.
- Declarative: Uses a Kotlin DSL or builder to declare pipeline schematics.
- Powerful: Supports both simple steps and complex synchronization structures like barriers and aggregators.
- Resilient: Pipe has resiliency baked-in. Has support for step retries in case of failures.
- Android arch-friendly: The API is designed with the Android architecture components in mind, making integration into your apps easy.
Consider a use case where we want to construct the following pipeline:
- Wait for a UI signal to start the pipeline (say, button click)
- Ensure that there is internet connectivity
- Download an image from the given URL
- Rotate the downloaded image by 90 degrees
- Scale the image to a 400px x 400px size
- Overdraw the scaled image on top if its sibling
Pipe uses a Kotlin DSL to declare pipeline schematics. We can express the above pipeline as:
data classImagePipelineMember(valurl:String? =null,valimage:Bitmap? =null)valJOBS_REPO=InMemoryRepository<Job<ImagePipelineMember>>()valLOGGER=AndroidLogger("Pipe")funmakePipeline()= buildPipeline<ImagePipelineMember> { setRepository(JOBS_REPO) setLogger(LOGGER) addManualBarrier("start_barrier") addManualBarrier("internet_barrier") addStep("download", attempts=4) {ImagePipelineMember(image= downloadImage(it.url!!)) } addStep("rotate") {ImagePipelineMember(image= rotateBitmap(it.image!!,90.0f)) } addStep("scale") {ImagePipelineMember(image= scale(it.image!!,400,400)) } addCountedBarrier("overdraw", capacity=Int.MAX_VALUE) { allMembers-> allMembers.mapIndexed { index, member->val siblingIndex=if (index==0) allMembers.lastIndexelse index-1val resultingImage= overdraw(member.image!!, allMembers[siblingIndex].image!!)ImagePipelineMember(image= resultingImage) } }}
We can then use this factory function to create an instance of the pipeline:
val pipeline= makePipeline()
And then schedule jobs into it:
constvalJOB_TAG="IMAGE_TRANSFORM_JOBS"fun Pipeline<ImagePipelineMember>.createImageJobs(imageUrls:List<String>):List<Job<ImagePipelineMember>> { countedBarriers.forEach { it.setCapacity(imageUrls.size) }return imageUrls.map { url-> push(ImagePipelineMember(url= url), tag=JOB_TAG) }}
We can subscribe to these jobs' state changes in our activities/fragments viaLiveData
:
val jobs= pipeline.createImageJobs(urls)jobs.forEach { job-> job.state.observe(this,Observer {// Update UI in response to state changes })}
See thestate machine for the details.
We can also fetch any ongoing jobs from the repository (e.g., if the fragment is re-created):
JOBS_REPO[JOB_TAG].forEach { (job, _, _)->// Perform actions on the jobs, such as interrupting them, unsubscribing from them, etc.}
To lift theinternet_barrier
automatically when we have internet connectivity, we can use one of theBarrierExtensions:
pipeline.manualBarriers[1].liftWhenHasInternet(App.INSTANCE)
And finally, we can start the pipeline when a UI button is clicked:
someButton.setOnClickListener { pipeline.manualBarriers[0].lift()}
The progress of a job is encoded via a state machine:
To see a full Android app example using the above pipeline, see thesample app. Or see the javadocshere.
About
Android library for building pipelines for executing background tasks
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.