From the course: Concurrent Programming with Android: Threads, Workers, and Kotlin Coroutines

Manage background tasks with threads

- [Instructor] In concurrent programming architectures, a thread let you manage a task in its own timeline. Android supports multithreading and each thread that you create explicitly will run in the background. That is separately from the user interface. In both Java and Kotlin, a thread is an object. There are a few different ways to create and start a thread in Kotlin. First I'll use code that mimics how you might write it in Java. It'll be a little verbose, but then I'll reduce it using Kotlin zone syntax. I'll create a variable named runnable, and as I did previously with handlers, I'll implement the runnable interface. And this is a lambda expression. So within the lambda, I'm going to create a for loop. I'm going to create a variable named I, and I'll set it from one to 10. So this loop will happen 10 times. Now within the loop, I'll call log I, and that expands to a call to log.i. Now change this to LOG_TAG. That's a constant that I've defined in my constants.kt file. For the message, I'll output looping, and then the variable I. At the end of the loop, I'll call log.i again, and pass in log tag, and then the message, all done. And I'll correct this code. And now, each time the runnable object is executed, I'll loop 10 times, and then I'll put the final message. Now, instead of using a handler object, I'll use a thread. I'll create a variable named thread, lowercase, and I'll initialize it by creating an instance of the thread class. And I'll pass in the runnable object. Then I'll call it thread.start. Now notice I'm calling log.i to output to the logcat console. I'm not trying to log to the user interface. And that's because I'm running in a background thread. When you're in a background thread, you do not have direct access to the UI. And if I tried to write to the TextView control, I would crash the application. I run the app, and before I test it on the device, I'll open up my logcat output. Then I'll go to the application and run the code. And I see the looping output right here. Now, it's all seems to be happening all at the same time. So I'll go back to my code, and in the for loop after I've output, each time through the loop, I'll call thread.sleep. And I'll pass in the value of 1000, for one second. If I were working in Java, I would have to wrap that code inside a try catch block. But Kotlin doesn't require that. So now, I should be able to run the application, and now I'll be going through the loop once each second. When you're running code in the background, you always want to ask the question, "Is the user interface still responsive?" To test that, I'll touch run code again, and wait a few seconds, then I'll touch clear. And I see that the log output on the screen goes away. That means that the user interface noticed when I touched that button, and the handler for that button was executed correctly. I now have two threads running simultaneously. The user interface and the background thread. Now, I'll shrink this code down, so it looks a little bit more like native Kotlin code. One simple approach, is to create the threat object like this. In Kotlin, you can assume that the thread object will take a runnable as its only parameter, so you only need the braces. And then at the end of the braces, you can call the start function. And you no longer need those two lines of code. I'll run the code again, and I see the code executing in the background, in the logcat window. And there's an even more elegant way to express this, using an extension function from the Kotlin concurrency package that's simply named thread. And it looks like this. I'll call the thread function, and this can receive a number of different arguments. I'll set start to true. And this means, execute this thread right away. And now, I no longer need the start function at the end. I'll run the code, and I see that the loop is executing. I'll touch the clear button, and see that the UI is still responsive. Now again, this thread function has a whole bunch of different parameters that you can use. You can set the throw to being a daemon or not, you can indicate whether there's a class loader, you can pass in a name, set the priority, and more. It's worth exploring this function to see what else you can do in Kotlin when working with threads with a tiny bit of code.

Contents