Hi,
I am back with another update. Today, I deal with orientation changes for both the activities (MainActivity and PostDetailActivity).
MainActivity
Let’s take the MainActivity first. It consists of a RecyclerView which displays the titles of all the posts fetched from the website. When I rotate the screen, it triggers another call to the internet to fetch data. We can see clearly, this last call is unnecessary as we already have the post objects list. Unnecessary network calls equal unnecessary network usage, the extra load on the battery and extra space.
Technically, when the orientation changes, Activity shuts down and restarts, calling separate AsyncTask which creates another background thread on which we communicate with the internet and fetch the data.
Or consider another scenario, we open the app, the current activity A creates a background thread 1 which sends a call to the internet. While the result is coming back, the user rotates the screen. Which restarts the current activity, call it B and creates another background thread 2 which also sends a call to the internet. Now there are two threads waiting for two network calls, equivalent to the extra network usage and longer time to get results. Also, the first async task will return data to an activity no longer there. These two backgrounds threads will keep on running until they get the result, resulting in extra memory usage.
To avoid this, I use AsynTaskLoader instead of AsyncTask which prevents duplicate loading. Loaders are registered with an ID by a component LoaderManager facilitating them to live beyond the lifecycle of the activity they are associated with. AsyncTaskLoader loads the data in the background thread. When the device is rotated, the LoadingManager makes sure running Loader connects to the onLoadFinished function. Loader loads in the background, and sends the result to the onLoadFinished function on completion.
Changes made in the MainActivity to incorporate AsyncTaskLoader –
- Delete inner class DDQueryTask.
- Implement LoaderManager.LoaderCallbacks<Post[]>.
- Override the methods onCreateLoader, onLoadFinished and onLoaderReset and implement them to load data in the background.
- Initialize the loader inside the onCreate method.
- Restart the loader when we click the REFRESH button on the menu.
After this, when we rotate the MainActivity we don’t see the data being reloaded.
WebView inside the PostDetailsActivity
When we click on a post in the MainActivity, it opens PostDetailsActivity which displays the URL in the WebView. When I rotate the screen, reloading happens. To prevent this we just need to add the following code to the PostDetailsActivity’s activity tag in AndroidManifest.xml. Here we don’t need to use AsyncTaskLoader or cache because the data is already there and we need to re-render it in the landscape view.
android:configChanges="orientation|keyboardHidden|screenSize
When we use android:configChanges, the activity won’t shut down and restart on screen rotation. Instead, the onCOnfigurationChanged method is called which handles the configuration changes automatically. When this method is called, the resources object gets updated with new resource values matching the new configuration.
Now when we rotate the PostDetailsActivity screen, the webview doesn’t reload the URL.
Files Changed:
- MainActivity.java
- AndroidManifest.xml
Today’s update took me 2 Pomodoros i.e. 50 minutes.
You can follow the development progress by visiting the DD Application Development Daily Progress page. The update on Day 3 is available here.
That’s all for today. See you in the next post.