An Android Apprentice’s journey to understand Pandora’s migration from AsyncTask to newer APIs

During my second month as an Android Engineer Apprentice, I was tasked with migrating AsyncTask to newer APIs. Early on, I was asked, “Do you know why we are migrating from AsyncTask?” I wracked my brain and answered shyly, “It has something to do with memory leaks?” I needed to learn more, so I researched furiously and discovered a multitude of motivating factors for converting AsyncTask to a more modern API.

To start my journey, I wanted to understand what problems AsyncTask originally solved. In the early days of Android, it wasn’t uncommon to manage threads manually. Managing threads is imperative to concurrency, which is where two tasks overlap in execution. In turn, concurrency is necessary in mobile development to provide a smooth user experience. To aid developers, Google introduced AsyncTask as a streamlined approach to thread administration.

AsyncTasks made thread management easier; however its use is error fraught. For example: memory leaks. These occur when unused objects accumulate in memory. AsyncTask has a persistent reference to the invoking object. The invoking object must account for the cancellation of AsyncTask to free up unused resources.

The cancellation of AsyncTask itself is fraught with potential issues. The work inside AsyncTask must run to completion before cancellation is exhaustive; the application is obligated to wait for ancillary work. As a consolation, there are ways to check for cancellation, leaping over subsequent work and completing.

The third and final topic of contention with AsyncTask: its use can be expensive. AsyncTask is a helper class around the Thread and Handler classes, the former granting Java access to new threads. Creating new threads include operations like system calls, allocation of memory for the new thread, and object creation to allow access to the new thread. This time introduces overhead, making AsyncTask’s use computationally expensive.