Once the difficult task of developing and testing the Content Downloader was completed, integrating it into the existing app was straightforward. Almost all content-related tasks can be performed using a handful of public methods inside a single ContentDownloader class. Those methods are called by the main app, depending on the actions the user performs while using the app. Almost all actions the user can perform have an effect on the downloader’s behavior.
In order to understand how the user’s behavior affects downloading, a quick overview of the app’s presentation is required. TalentLMS for Android presents content hierarchically, starting with the Course List Screen which is presented to the user right after they sign in.
When a Course in this list is tapped, the Course Details Screen is presented. This screen contains all information about the Course, as well as a list of its Units. When the user taps on a Unit, they are presented with the Unit Screen, which contains the actual content.
Courses list screen -> Course details screen -> Unit screen
As the user navigates between screens and provided that the device is online, Unit content, and Unit and Course metadata have to be continuously fetched and updated from both TalentLMS and third-party servers.
Metadata are transferred from various endpoints of the TalentLMS REST API as JSON messages which are relatively small in size, but the actual multimedia content of Units can be anything from a few kilobytes to multiple gigabytes of data.
While most metadata for the Course List and Course Details screens are downloaded automatically, Unit content downloading is only triggered by user actions that indicate interest towards a certain Course or Unit. That way, the network, CPU and storage subsystems are not utilized unnecessarily for content that the user might not need.
Before a Unit download actually starts, it is added to the downloads queue. The downloader sorts this queue by priority and checks it whenever new Units are added, or the status of previously-queued Units changes (status changes can occur due to failures, download completion or stopping etc.). Whenever a new download slot becomes available, the Unit with the highest priority begins downloading.
Units are queued for downloading via two different user actions:
1) User taps on the SYNC ALL button in the Course Details screen
This action adds all not-yet-downloaded Course Units to the top of the queue. Their relative order is determined by their types and their order of appearance in the Course list. Units with large multimedia content are downloaded after Units with small content and Units higher up in the Course list are downloaded before Units further down the list.
This type of prioritization improves the UX greatly in many situations because it increases the perceived speed of the app. Unless the Course is comprised mostly of Units with large content, all smaller Units will finish downloading soon, giving the impression that a lot of progress has been made quickly.
Downloading of all course units via SYNC ALL UNITS button
While download prioritization is important, it won’t matter at all unless the downloads queued are actually started soon. To ensure that downloading starts and finishes as soon as possible, previous Units that are currently being downloaded and do not belong to the newly queued list of units are paused. The result is that content which the user has most recently requested and is most likely to view next will become available as soon as possible.
2) User taps on a Unit
When the user is attempting to view a single Unit, it is imperative that they do not have to wait any longer than necessary. If the Unit’s content has not been downloaded, that is ensured by pausing all Units currently downloading before enqueuing the Unit, giving it full priority.
When that happens, the downloader is limited to one concurrent download, so that all available bandwidth is allocated for the current content only. Once the download has finished, the number of concurrent downloads is restored to their maximum values and all downloads are resumed.
Downloading a single unit by tapping on it from the list
Units that only support streaming content such as YouTube and Vimeo videos, also have the effect of pausing all downloads to free up bandwidth and provide smooth playback.
Every time the user navigates to the previous or next Unit via the Unit screen arrow buttons, the above rules are enforced again.
Although Unit priorities are set when they are first added to the downloads queue, they do not remain unaffected. Whenever the user expresses interest in different content by navigating closer to it, priorities are updated to make sure that content will become available as soon as possible.
Specifically, when a user navigates to a Course that has Units queued but not yet downloaded, these Units get the highest possible priority in the same way as if the user had just pressed the SYNC ALL button. Additionally, all actively downloaded Units not belonging to the Course are paused. Finally, when the user navigates to a Unit that is queued or is still downloading, all other currently downloading Units are paused.
Handling network state
Network state changes also affect the Content Downloader behavior. Three different states are handled:
No Internet access
The Content Downloader is paused so as to avoid retrying queued downloads and conserve battery. The user is served offline content and is notified when that is not available.
There are two possible ways to handle this state in TalentLMS for Android. The default state is to avoid downloading any large content when that is not absolutely necessary. That means that when the user taps on the SYNC ALL button of a course, only the course metadata and small content is downloaded. Larger content files such as video or audio are only downloaded when the user attempts to view those specific units.
The above behavior can be changed by the “Wi-Fi Download Only” option in the Settings Screen. When this option is disabled, the behavior of Wi-Fi and mobile data connections are the same.
The downloader attempts to download all queued content following the rules described in the previous sections.
You can read more about the architecture of the TalentLMS for Android Content Downloader in part 3 of this series of articles on the behind-the-scenes power that makes our mobile app faster and more efficient that ever.