In every Android app, there's a single foreground thread known as the main thread. This thread manages the user interface. All visual elements such as layouts and widgets are a part of the main thread and most of the code that you write in an activity class is executed on that thread. But it's only a single thread, which means only one thing can be happening at a time. When you need to do things in an Android app that might take a few seconds, such as a network request, you have to make sure you're not blocking the main thread.
- [Instructor] In order to communicate with resources on the web from an Android app, you need to understand a little bit about concurrency. That is, the ability to use background threads. In recent versions of Android, network communications must happen on a background thread, each application has a single foreground thread, sometimes known as the main thread or the UI or user interface thread. This is the thread that controls animations and visual presentation. All the visual elements of your application are on that main thread, but when you want to communicate over the web, that is, make requests and receive responses, that communication has to go on a different thread, so that you don't freeze the user interface while communications are going on.
The rule is, don't block the main thread. You need to know how to do asynchronous communications or at the very least, launch synchronous communications on a background thread so both things can be happening at the same time. Because the user interface is on one thread, and your network communications are on another, you can't directly access one from the other, so you need ways of sending messages between the two threads. Android has some built-in tools that you can use to accomplish this, and I'll talk through a few of them now.
As I mentioned, network communications have to run in the background, you could do all the work yourself by using standard Java concurrency tools, these include classes like Thread, Runnable, and other components from the package java.concurrent. But if you do it that way, you'll be reinventing a lot of wheels. A lot of these problems have already been solved for you by components that are included in the Android SDK. For example, there are two classes named AsyncTask and AsyncTaskLoader.
AsyncTask is a part of the core SDK and AsyncTaskLoader is provided in the support repository. And there's also another incredibly valuable architecture known as an IntentService. Here are the differences between them and some of their relative advantages and disadvantages. The AsyncTask class is a wrapper around a thread. It's designed for use for short tasks that last only a few seconds. In order to use AsyncTask, you typically define your own class that extends AsyncTask, and it's commonly defined as a member class of the activity that's going to use it.
Each instance of an AsyncTask class can only be executed one time. So you create the AsyncTask object, you call it's execute method and then you discard it. The nature of an AsyncTask is that it's a wrapper around a background thread, and it has a set of methods. One of those methods runs in the background, and the rest run in the foreground. And it gives you ways of passing information back and forth between the two threads. Each instance of an AsyncTask is bound to whatever class instantiated it.
Typically an activity, but it has one important restriction, AsyncTask objects don't survive configuration changes, so if you launch a long-running AsyncTask and then the activity that launched it changes configuration, such as changing orientation from portrait to landscape or back again, that AsyncTask object will be killed and the task won't complete. There are ways of getting around this, such as wrapping AsyncTasks in fragments, but that takes a lot more work, and so instead, a lot of developers turn to the next architecture know as an AsyncTaskLoader.
This class is included in the support repository, it's a loader wrapper for an AsyncTask. The loader architecture in Android gives you a way of working with remote data without worrying about configuration changes. Because loaders are designed to survive configuration changes such as changes in orientation, because of this architecture, the AsyncTaskLoader works well with fragments, just like AsyncTask, the AsyncTaskLoader is typically defined within a class, usually the activity that it's going to serve data to.
And so those two classes, AsyncTask and AsyncTaskLoader, are commonly used when you don't mind binding the functionality to a single activity in the application. If you do want to completely decouple your network communications from the user interface, the next architecture will do the job for you. It's call an IntentService. It's a service which always runs in the background, just like other services, but an IntentService has a very specific purpose and architecture. It's designed to be able to run longer request/response cycles, so if you're doing something that's going to take a little while, such as downloading a lot of data, or downloading larger files, doing it in an IntentService is highly reliable.
You define an IntentService in its own class. And you register it in the application manifest. You can then launch an IntentService by creating an Intent object that packages up the instructions and then you call it just like you would when you launch an activity or any other kind of service. An IntentService stays in the background until its task is complete and then it unloads itself automatically. If you want to execute multiple background actions, one after the other, you can launch multiple IntentService objects and each one will run until it's done and the next one will then start itself.
So they run serially rather than consecutively. Because the IntentService is completed decoupled from the user interface, you need a way to pass data back to that user interface thread and this is typically done with broadcast messages. You package up the information you want to share, as an Intent, and then you pass it back to the rest of the application with the broadcast message, any activity or other component that wants to listen for those messages can do so. So an IntentService can share data with any component in the application, it doesn't even need to know who it's sharing it with, it simply broadcasts the message and then anything in the application can listen for and handle the message when it occurs.
So all three of these architectures can be used to effectively run tasks on background threads. AsyncTask, AsyncTaskLoader and IntentService, and I'll show you how to use all three of these in this course.
IInstructor David Gassner starts with an overview discussion about available networking strategies, and then dives into how to declare networking permissions, make network requests, handle responses, parse data returned from a web service, and pass user credentials to services that support HTTP basic authentication. He also provides an overview of popular higher-level networking libraries, including OkHttp and Picasso, and offers recommendations for improving performance in network-connected apps. David also covers using static feeds, using dynamic PHP pages hosted on a public server web service, and integrating apps with network data storage.
- Integrating mobile apps
- Communicating with Android
- Preventing app freezes with background threads
- Preparing an app for network communication
- Declaring permissions
- Checking network connectivity
- Retrieving data over the web
- Using traditional APIs
- Using third-party libraries