1page.title=Redundant Downloads are Redundant 2parent.title=Transferring Data Without Draining the Battery 3parent.link=index.html 4 5trainingnavtop=true 6previous.title=Minimizing the Effect of Regular Updates 7previous.link=regular_updates.html 8next.title=Connectivity Based Download Patterns 9next.link=connectivity_patterns.html 10 11@jd:body 12 13<div id="tb-wrapper"> 14<div id="tb"> 15 16<h2>This lesson teaches you to</h2> 17<ol> 18 <li><a href="#LocalCache">Cache files locally</a></li> 19 <li><a href="#ResponseCache">Use the HttpURLConnection response cache</a></li> 20</ol> 21 22<h2>You should also read</h2> 23<ul> 24 <li><a href="{@docRoot}training/monitoring-device-state/index.html">Optimizing Battery Life</a></li> 25</ul> 26 27</div> 28</div> 29 30<p>The most fundamental way to reduce your downloads is to download only what you need. In terms of data, that means implementing REST APIs that allow you to specify query criteria that limit the returned data by using parameters such as the time of your last update.</p> 31 32<p>Similarly, when downloading images, it's good practice to reduce the size of the images server-side, rather than downloading full-sized images that are reduced on the client.</p> 33 34<h2 id="LocalCache">Cache Files Locally</h2> 35 36<p>Another important technique is to avoid downloading duplicate data. You can do this by aggressive caching. Always cache static resources, including on-demand downloads such as full size images, for as long as reasonably possible. On-demand resources should be stored separately to enable you to regularly flush your on-demand cache to manage its size.</p> 37 38<p>To ensure that your caching doesn't result in your app displaying stale data, be sure to extract the time at which the requested content was last updated, and when it expires, from within the HTTP response headers. This will allow you to determine when the associated content should be refreshed.</p> 39 40<pre>long currentTime = System.currentTimeMillis()); 41 42HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 43 44long expires = conn.getHeaderFieldDate("Expires", currentTime); 45long lastModified = conn.getHeaderFieldDate("Last-Modified", currentTime); 46 47setDataExpirationDate(expires); 48 49if (lastModified < lastUpdateTime) { 50 // Skip update 51} else { 52 // Parse update 53}</pre> 54 55<p>Using this approach, you can also effectively cache dynamic content while ensuring it doesn't result in your application displaying stale information.</p> 56 57<p>You can cache non-sensitive data can in the unmanaged external cache directory:</p> 58 59<pre>Context.getExternalCacheDir();</pre> 60 61<p>Alternatively, you can use the managed / secure application cache. Note that this internal cache may be flushed when the system is running low on available storage.</p> 62 63<pre>Context.getCacheDir();</pre> 64 65<p>Files stored in either cache location will be erased when the application is uninstalled.</p> 66 67<h2 id="ResponseCache">Use the HttpURLConnection Response Cache</h2> 68 69<p>Android 4.0 added a response cache to {@code HttpURLConnection}. You can enable HTTP response caching on supported devices using reflection as follows:</p> 70 71<pre>private void enableHttpResponseCache() { 72 try { 73 long httpCacheSize = 10 * 1024 * 1024; // 10 MiB 74 File httpCacheDir = new File(getCacheDir(), "http"); 75 Class.forName("android.net.http.HttpResponseCache") 76 .getMethod("install", File.class, long.class) 77 .invoke(null, httpCacheDir, httpCacheSize); 78 } catch (Exception httpResponseCacheNotAvailable) { 79 Log.d(TAG, "HTTP response cache is unavailable."); 80 } 81}</pre> 82 83<p>This sample code will turn on the response cache on Android 4.0+ devices without affecting earlier releases.</p> 84 85<p>With the cache installed, fully cached HTTP requests can be served directly from local storage, eliminating the need to open a network connection. Conditionally cached responses can validate their freshness from the server, eliminating the bandwidth cost associated with the download.</p> 86 87<p>Uncached responses get stored in the response cache for for future requests.</p>