This is a continuation of our post discussing different areas of android development. We are getting introduced to android development while developing an application GitHub Contributions App.
There are a number of ways we can delay processing of some work in android. It also allows us to execute these work items on a periodic basis. There are a number of options for an android developer for introducing scheduled execution.
Refactoring the code
Before we start scheduling the work, we know that the scheduled download would involve getting the online data. Our current AsyncTasks would not support so. They would check if we have recent data in the files and would provide the data stored in file to the activity. So we need to refactor the code to separate the data load from internal storage and online. Let’s first create these base classes. They would be extended by their specialized classes for internal storage and online.
Here are the extended types to support loading user profile information from online and internal storage. The online version, in addition to download information, also serializes the info.
Similar should be the implementation for specialized types for repository data. It also has two types to download the same details.
When to load information from Internal Storage
We should remember that we only need to load information from internal storage when the application is launched. After every periodic load of information every three hours, it is download form online github profile of the user. Let’s introduce a boolean flag isLoaded. The flag is initially reset. After the application is loaded by finishing execution of onCreate(), the flag is set.
We have also updated the definition of loadUserDetails() to use this flag. Since the same method is used for initial and all the subsequent load of information, the above code should ensure that the async tasks loading information from internal storage are only used the first time. They would also not be used when the information in the internal storage is not current.
Using Scheduled Executor Service
There are number of options available for periodic execution of code in android. ScheduledExecutorService is one such option. It provides options for these executions at fixed rate or intervals.
We can use Executors type to get an instance of ScheduleExecutorService. Executors is a type available in java.util.concurrent package. It provides factory methods for Executor, ExecutorService, ScheduledExecutorService and ThreadPoolExecutor.
Other Options for Delayed / Periodic Executions in Android
Android has a number of other options to post a single or periodic executions of some code block. Let’s briefly discuss some of them.
Handlers are used to delay the execution of some code and post it after the specified delay. It can also use a HandlerThread to support executing on a different thread.
There is no associated message loop for a thread. Looper can be used to create a message loop for a thread. HandlerThread provides a message loop which can be used by Handler instance.
Since we don’t just need to delay the execution butt we need to introduce periodic execution, we have avoided using Handler type for our case.
If you are coming for a non-android platform, then this is the first option you would think about for scheduled execution. There are a number of timers you might be used to in C#. You might want to dig for single and multithreaded timers. We can introduce timers to delay processing of some work (one-shot) or performing it on a periodic basis (recurring). They can also be fixed-period or fixed-rate. The former ensures every-next execution to start based on the start time of the previous execution, while the latter would just fire-off every time the duration lapses without any consideration of possible delay starting the previous run. There are a number of schedule() methods available in the Timer for choosing among these modes.
Timers can be created to execute on a user or daemon thread. For .net developers, they are respectively similar to foreground and background threads.
It must be remembered that Timers are not recommended for newer development using Android. Developers are encouraged to use ScheduledThreadPoolExecutorService.
AlarmManager can also be used to execute some code block at some later time. It can also be used to execute it on periodic basis. But this is more system wide approach. Beginning API 19, Alarms are also not exact. Details here.