Notes: 02. Launch Threads & Post to the Main Thread
The student materials have been reviewed and are updated as of SEPTEMBER 2022. The image desplayed for the first project(and therefore its url) has changed. Don’t worry, the code stays the same :]
This course has a few sample projects you’ll use to learn about background processing in Android.
The first and the last part of the course projects are already set up, and they’re the same ones used in the Kotlin Coroutines: Fundamentals course. You don’t need to set them up yourself. But the second and third parts of the course use a separate app called Memories, which you’ll set up later.
For now, you’ll work on the introduction app, which you only need to open. To open the projects, you need Android Studio 3.6 or greater, which you should have installed, if you’ve been following our Android learning path.
If not, head over to the official Android Studio download website, and install the tool. You can leave all the default options when installing it. Then open the IntroApp project, within the student materials for this course.
[Swith to demo of the main project]
After you open the project, it should sync. Then you can use it. For now, the project doesn’t do much, and it only has one class - the MainActivity.kt. The idea behind the project is to download an image, and display it the app.
Through this seemingly small task, you’ll repeat concepts you’ve learned in previous courses about threading and networking, and learn about the WorkManager.
val imageUrl = URL("https://cdn.pixabay.com/photo/2018/01/14/23/12/nature-3082832__480.jpg")
val connection = imageUrl.openConnection() as HttpURLConnection
connection.doInput = true
connection.connect()
val inputStream = connection.inputStream
val bitmap = BitmapFactory.decodeStream(inputStream)
image.setImageBitmap(bitmap)
This piece of code uses an HTTP connection to download the image, and build a bitmap, which you display in the app. Run the project on an emulator, to see what happens.
And the app seems to crash! This is because you have to fix the way the app handles threading.
If you’ve watched the previous courses on threading, you already know where the problem lies. If not, let’s revise.
Every Android app has a single Main thread that draws the user interface. The main thread is responsible for everything that has to do with the visual side of the app, as well as some simple operations you can execute very fast.
But because the main thread has to be fast and free to draw the UI, you cannot have long running blocking operations on it, such as downloading an image, or reading from the database. If you try to run a heavy operation like that on the main thread, Android will crash your program.
To avoid this, all you need to do is start your work in a background thread, by using predefined mechanisms like Coroutines, or by starting your own threads.
But when you get your result, like a bitmap, you need to display it again. And you can’t update the UI from anywhere other than the main thread. So to display the image, you need to post back to the main thread, using mechanisms like Handlers or the runOnUiThread() function.
Let’s implement proper threading, using the concepts from previous courses!
To switch to a background thread, add the following code:
Thread(Runnable {
}).start()
Wrapping your code in a Runnable, which will be executed on a new thread, will relieve the main thread from work, and let you download the image. Then when you want to display the image, you need to switch to the main thread. Do that the following way:
runOnUiThread { ... }
Now wrapping the display code in this block will move it to the main thread. Run the project now, and you should see the image being displayed!
That’s it! Well done! You’ve successfuly used threading to switch to the background to fetch the image, and then post the result to the main thread.
Now that you’ve revised how to work with threading, you can proceed to the next episode, where you will learn about WorkManager, an API in Android which helps you achieve the same behavior, and much more! :]