Kotlin Coroutines Job Example

In this blog, we will learn about Coroutines Job in Koltin. Using the Coroutines Job how we can handle the peace of code that is running in the background. So let’s started.

What is Jobs

Basically, Job in the context of Coroutines is handled on that Coroutines piece of code that is running in background. So a .launch() call returns a Job. Using that Job you can manipulate the lifecycle. Let briefly explain about Coroutines Jobs

  • Jobs allows us to manipulate the coroutine lifecycle
  • Jobs have a hierarchy, So Jobs live in the hierarchy of other Jobs

Job Example

//Jobs hierarchy
Job1 {
	Job2 { }
	Job3 {
		Job4{ }
	}
}

You have a Job here that has two children( Job1 and Job2 ) and one of the children has another child. So you have a hierarchy of Jobs. So this is how you can create a Job or a Job within a hierarchy. Let’s take one more example.

Job Example

val job1 = GlobalScope.launch {
	coroutineScope {
		val job2 = launch {
		// processing
	}
}

In this example, You have a job here, and it created when we launch on GlobalScope. Inside that global scope, we created a coroutine scope and inside that, we launch our job2. So in this particular example job2 lives inside job1.

Job lifecycle variables and method

So you can access lifecycle variables and methods using the job. These are

  • cancel()
  • join()

So things like cancel() that allow us to cancel a job and join which basically join the coroutine to the current thread, to the main thread usually.

Now importantly If a job is cancelled, all its parents and children will be cancelled too. So these Job within a hierarchy depends on each other. and one is cancelled then other will be cancelled as well. Let’s understand it below example

Example of Job

So let go ahead a create few job in a kotlin class in main function, just like below

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    runBlocking {
        val job1 = launch {
            println("Job1 launched")
        }

        job1.invokeOnCompletion { println("Job1 completed") }
    }
}

As you have seen, first I have created runBlocking() to create a coroutine context or coroutine scope. And inside here I’m gonna have a job named is job1.

So after I have created and launched Job 1, on completion what I would like to do, just println(“Job1 completed”) using invokeOnCompletion(). So this is an invokeOnCompletion method a hook that we can use to process some code when the job is completed, whether it canceled or finished by itself. Let go ahead and run the code as it now

Output

Job1 launched
Job1 completed

As you have seen, job has launched and completed. Now we have job1 launched and we use that job object to attached some fictionality to on it completion.

Cancel the Job in Coroutines

Using the above block of code, I would like to cancel this job it is still running and see what its the outcome will be. So, first of all, I need to put a delay here inside the job otherwise the job would run immediately.

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    runBlocking {
        val job1 = launch {
            delay(3000L)
            println("Job1 launched")
           
        }

        job1.invokeOnCompletion { println("Job1 completed") }

        delay(500L)
        println("Job1 will be canceled")
        job1.cancel()
    }
}

Output

Job1 will be cancelled
println("Job1 will be cancelled")

Now importantly println(“Job1 launched”) is not execute anymore because we are having a delaying half a second and then we are saying to jump on canceled, then we are canceling it. So let run this code and see the output. first, call println(“Job1 will be canceled”) then job1.invokeOnCompletion { println(“Job1 completed”) }. invokeOnCompletion run whether the job finishes by itself or is canceled. So we are getting ‘Job1 completed’

Create a hierarchy inside the Job in Coroutine

Now what I would like to show you is, how we can create a hierarchy inside the Job. then see what happens when we actually cancel the Job. and whats happens in that Job hierarchy.

import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking

fun main() {
    runBlocking {
        val job1 = launch {
//            delay(3000L)
            println("Job1 launched")
            val job2 = launch {
                println("Job2 launched")
                delay(3000L)
                println("Job2 is finishing")
            }
            job2.invokeOnCompletion { println("Job2 completed") }

            val job3 = launch {
                println("Job3 launched")
                delay(3000L)
                println("Job3 is finishing")
            }
            job3.invokeOnCompletion { println("Job3 completed") }
        }

        job1.invokeOnCompletion { println("Job1 completed") }

        delay(500L)
        println("Job1 will be cancelled")
        job1.cancel()
    }
} 

So inside the Job1, we have launched Job1 launched. In this hierarchy I have created 2 more jobs, that is Job2 and job3. Inside these jobs, we have a println(). Here we have a delay of 3 seconds. After that, we have again println. At the last we calling invokeOnCompletion(). All done let go ahead and run this code.

Job1 launched
Job2 launched
Job3 launched
Job1 will be cancelled
Job2 completed
Job3 completed
Job1 completed

All right, as you have Job1 launched, Job2 launched and Job3 launched. Now impotently we’re never getting Job2 is finishing and Job3 is finishing, why because we are getting job1 will be cancelled. Then we are proceeding to actually cancel that job. and we can see (Job1 will be cancelled) that we are cancelling Job1, therfore we are cancelling job2 and job3. That why we are getting Job2 completed, Job3 completed and then Job1 completed. So the whole hierarchy will be cancelled, If one of the job will be cancelled.

So that is how you play around with jobs. You can the job object to invoke lifecycle methods on that particular Coroutines.

Conclusion

That all about jobs in Coroutines. In this blog, we have learned how jobs allow us to manipulate the coroutine lifecycle, and how the Jobs hierarchy works. I hope it will help you a lot, I would like to invite you to read our coroutines series. Thanks for reading

Happy coding 🙂

Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments