Android Development

Google's android guide Home Contact

Networking built-in with SDK

For using the built-in networking capabilities provided by Android with SDK without use of any third party libraries, these are the few options:

Thread with Handlers using HttpURLConnection

HttpURLConnection class is part of the Java standard library and is accessible in Kotlin for Android as well because Kotlin is fully interoperable with Java. It can establish HTTP connections and perform basic GET, POST, PUT, and DELETE requests. It is used inside a background thread to perform network operations asynchronously to prevent blocking and freezing the main/UI thread. To update the UI related code which runs in main thread a Handler class can be used (no third party use option) to pass messages or runnables from background thread where HTTPURLConnection is made. In the Handler's handleMessage() or post() method, the UI components can be updated. Using threads with handlers is not best for more complex scenarios or when dealing with asynchronous operations and concurrency control. For parallel execution of multipletasks, and managing thread synchronization use other options with Android SDK, such as ThreadPoolExecutor or Coroutines (using Kotlin).

ThreadPoolExecutor

'ThreadPoolExecutor' is used to manage a pool of worker threads for executing tasks concurrently. It performs parallel processing and handle multiple tasks simultaneously with concurrency control (maximum number of threads, thread pool size, and thread idle timeout) and without blocking the main thread. When using a 'ThreadPoolExecutor' and background threads for executing tasks, the 'runOnUiThread' method is one way to update the UI from a background thread or create an instance of Handler associated with the main/UI thread and use it to post Runnable objects to the main/UI thread's message queue. By posting a Runnable to the Handler, the UI can be updated from a background thread.

Steps to use ThreadPoolExecutor:

  • Create a ThreadPoolExecutor: Create a ThreadPoolExecutor by specifying various parameters like the core pool size, maximum pool size, keep-alive time, and a BlockingQueue to hold tasks.
  • Submitting Network Calls as Tasks: Submit network calls (or any other tasks) to the ThreadPoolExecutor for execution. Wrap the network call in a Runnable or use Callable if a result need to be returned.
  • Handling Callbacks: Since network calls are typically asynchronous, there is a more than one way to handle the results or callbacks when the task is complete.
    1) Post a Runnable with the result to the main UI thread using a Handler.
    2) Use libraries like LiveData or RxJava to handle asynchronous tasks and observe the results in a more reactive way.
    3) Define custom callback interfaces to handle the results when the network call is complete.
  • Handling Errors: Handle errors and exceptions that might occur during network calls. Use try-catch blocks within the Runnable to handle exceptions.
  • Shutdown the Executor: Shut down the ThreadPoolExecutor when it's no longer needed, typically in your app's lifecycle methods like onDestroy() of an activity or onStop() of a fragment. This prevents thread leaks and frees up resources.

Coroutines

Using coroutines, network-related code can be written in a sequential and concise manner, without blocking the main thread. Coroutines handle the low-level details of threading and scheduling, making it easier to write asynchronous code that is more readable and maintainable. Coroutines abstract away the complexities of managing threads. There is no need to manually create and manage threads or worry about thread synchronization. The dispatchers provided by coroutines handle thread pooling and thread switching, making it easier to write concurrent code. Coroutine can be launched using the launch builder function or other coroutine builders. The coroutine will run concurrently with the main/UI thread. Inside the coroutine, there is need to update the UI, which can be done after switching to the main/UI thread using the withContext function and specifying the Dispatchers.Main dispatcher.

A sample code using corouties can be found at: Fetching JSON data using Coroutine.

Networking using external libraries

While use of no third party networking libraries can have some inherent advanatges and may also be suitable if a company's such non-use policy requires it, however there are many stable libraries which can help reduce boiler plate code and offer some advanced features such as automatic request/response serialization, network caching, retry policies, connection pooling, and interception for custom behaviors. Some of the most common such options include:

Retrofit: Retrofit is one of the most popular networking library that simplifies the process of making HTTP requests and processing responses. It offers a high-level API, supports various request types (GET, POST, etc.), handles serialization/deserialization of JSON/XML, and provides features like request/response interception, authentication, and error handling.

OkHttp: OkHttp is a versatile and efficient HTTP client library for Android. It offers a simple and easy-to-use API, supports features like connection pooling, request/response caching, interceptors, and authentication. OkHttp can be used independently or in conjunction with Retrofit for network operations.

Volley: Volley is a powerful networking library provided by Google. It offers an extensive set of features, including automatic request prioritization, request/response caching, batched requests, image loading, and support for multiple protocols. Volley is suitable for small to medium-sized network operations.

Ktor: Ktor is a modern, asynchronous networking library built by JetBrains. It offers a multiplatform framework for building HTTP clients and servers. Ktor provides a flexible API, supports coroutine-based programming, and offers features like routing, authentication, and extensibility.