This is a continuation of a post for building an android app for displaying GitHub contributions of a user. We are using name of user for pulling down profile and repository details of the user. As we are adding features to the app, we have been learning about android and its development model.
Currently we are at the point that we can download the data asynchronously and display it on the UI. User can also change user and the data is downloaded for the new user. In this post, we want to build up on this by adding the following:
Keep the data in a file so that when the app needs it it can just be pulled from a file rather than being downloaded from the web. This can also cater to the offline scenarios when the app is launched while being disconnected from the network. We also don’t need to download data if the app is launched within 3 hours of when the data was downloaded last time.
Since a picture is worth a thousand words, let us try to depict the storage model for android apps.
There are basically two types of storage available for an android app. They are internal and external storage. Here internal storage is an always available storage with the contents only visible for the app under consideration. Au contraire, the contents of external storage are accessible to other apps plus it may or may not not available. An uninstall removes all app data except the data specifically in the public area of external storage.
Since we don’t need to share GitHub contribution’s data with any other app, we will be keeping it in internal storage. The data would include profile and repository data for a GitHub user. In order to make our life easier, we will be keeping the data in JSON format.
Let’s add a serializer to manager persistence of profile and repository data. The responsibility of serializer is to serialize / deserialize profile and repository data. It also needs to check if the files are current. The definition of current in our system is that it is not older than 3 hours.
Checking if Data is Current
In order to avoid frequently download the user information, we have decided to keep it in a file storage. We need to check the file’s last modified date for our decision to download. Now this would require comparing the last modified date of file to the current machine’s time. Here we are using Calendar to get the current time. The literal integer value is the number of milliseconds for 3 hours. So if the duration is lesser than 3 hours, it is OK to get it from persistence. In order to keep things simpler, we are just checking for file to save repositories data.
Serialization Data Format
In order to serialize we can simply convert the data in to byte. We can then push the byte array to internal storage using FileOutputStream. We would be creating this after serializing it in JSON format. We can simply read data using FileInputStream. Here is the code we are using to save data to internal file storage and getting the data from it.
As discussed above, data is being converted to JSON format before sending it out to the storage. For our project, we are using GSON library for this conversion. Earlier we have discussed how we can add a JAR library to a project in Android Studio.
Since we have bitmap data in the profile, we are creating a memento for holding profile data excluding avatar’s bitmap. The bitmap is saved in a separate file.
Download Vs Load from Internal Storage
We have separate AsyncTask (s) for providing the profile and repositories data. Currently it just downloads it. Here we can make a decision to download it only when data is not current. Following is the code for providing profile data. It is using the same isPersistedDataCurrent from PersistenceHandler to check if data is current.
And we have similar code for repositories data.