{"id":1537,"date":"2015-04-26T23:00:27","date_gmt":"2015-04-26T17:30:27","guid":{"rendered":"https:\/\/www.innovationm.com\/blog\/?p=1537"},"modified":"2015-05-08T09:42:46","modified_gmt":"2015-05-08T04:12:46","slug":"lazy-loading-and-memory-management-of-images-in-listview-in-android","status":"publish","type":"post","link":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/","title":{"rendered":"Lazy Loading and Memory Management of Images in ListView in Android"},"content":{"rendered":"<h1 style=\"text-align: justify;\"><span style=\"color: #0000ff;\">Introduction to Lazy Loading<\/span><\/h1>\n<p style=\"text-align: justify;\"><strong>What is lazy loading? <\/strong><\/p>\n<p style=\"text-align: justify;\">A little introduction of lazy loading is \u00a0<em>it is a design pattern to defer the initialization of an object until the point at which it is needed.<\/em> In simple words create objects when it is needed.<\/p>\n<h1 style=\"text-align: justify;\"><span style=\"color: #0000ff;\">Problems to Tackle<\/span><\/h1>\n<p style=\"text-align: justify;\">Before talking about lazy loading of images, I want to mention about problems \/ issues associated in handling images in ListView \u00a0\/ GridView in Android. These are:<\/p>\n<ol style=\"text-align: justify;\">\n<li style=\"text-align: justify;\"><strong>Scrolling is blocked \/ interrupted<\/strong> &#8211; Downloading images from server OR loading from device local storage is heavy task and it may take some time. If you load \u00a0images directly in getView() method of Adapter then it blocks the UI thread and your ListView scroll will be interrupted and not smooth. You \u00a0need a mechanism to load images in a worker (separate) thread and show a place holder image until the image in not downloaded and placed in memory for fast access. Remember accessing images from Hard disk may also takes some time.<\/li>\n<li><strong>App Heap Memory can overshoot<\/strong> &#8211; If we load many images in memory for faster access by ListView \/ Adapter, then memory (heap memory) allocated to the application might overshoot and app will crash with Out of Memory (OOM) error.<\/li>\n<li><strong>Work with Recycling of Views can be tricky<\/strong>\u00a0&#8211; When image is \u00a0downloaded \u00a0we need to \u00a0decide when to set a particular image in its ImageView of that row it is meant for. \u00a0It may be possible that the ImageView object will recycle and it \u00a0is given to another image and\u00a0we end up showing wrong image.<\/li>\n<\/ol>\n<h1 style=\"text-align: justify;\"><span style=\"color: #0000ff;\">Solution<\/span><\/h1>\n<h3>Memory Locations &#8211; Space Vs Accessibility:<\/h3>\n<p>There are 3 locations where images are stored. Their comparison on <span style=\"text-decoration: underline;\">Memory space availability<\/span> and <span style=\"text-decoration: underline;\">Accessibility speed<\/span> is given below:<\/p>\n<ol>\n<li>Server (Memory Space is HIGH but Accessibility is SLOW)<\/li>\n<li>Hard Disk on Mobile (Memory\u00a0Space is MEDIUM and Accessibility is MEDIUM)<\/li>\n<li>Heap Memory (Memory\u00a0Space is LOW and Accessibility is FAST)<\/li>\n<\/ol>\n<p>We need to create a balance among above 3 locations for optimum utilization of accessibility and memory space.<\/p>\n<h3><span style=\"color: #000000;\">Mappings:<\/span><\/h3>\n<p style=\"text-align: justify;\">4 Mappings are required to manage the show. I have given them names. These are<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>Bitmap Cache Map<\/strong>\u00a0 (Unique Id of Row <strong>TO<\/strong> Bitmap of Image)\u00a0<strong>\u00a0&#8211;\u00a0<\/strong>LruCache class provided in Android SDK to store images in memory (Heap) will be used here. LruCache will act as cache and will also recycle the images after a certain limit is reached.<\/li>\n<li><strong>ImageView Recycler Map<\/strong> (Row ImageView Object\u00a0<strong>TO<\/strong>\u00a0Unique Id of Row)\u00a0&#8211; We will maintain a mapping of ImageView and Id of Row to identify visible views and accordingly set images on ImageView.<\/li>\n<li><strong>Image Loader \/ Downloader Queue<\/strong>\u00a0(Unique Id of Row <strong>TO<\/strong>\u00a0Row ImageView Object <strong>TO<\/strong>\u00a0URL of Image)\u00a0<strong>\u00a0&#8211; \u00a0<\/strong>Queue of\u00a0requests to load images (if available) from device local storage to Bitmap Cache OR download images from server and store them in device local storage and then place in Bitmap Cache Map.<\/li>\n<li><strong>Image Download Tracker<\/strong> (Image URL <strong>TO<\/strong> Status of Download) &#8211; This will map the URL and the status of image that is being downloaded from the URL. It is possible that request to download the same image comes and that image is already in process of downloading. This tracker will help to ignore such requests.<\/li>\n<\/ol>\n<h3 style=\"text-align: justify;\"><span style=\"font-size: 1.285714286rem; line-height: 1.6; color: #000000;\">Sequence of Steps:<\/span><\/h3>\n<p style=\"text-align: justify;\"><span style=\"text-align: justify;\">1. User comes to ListView. Adapter.getView() is fired for a single row. getView() will make an entry in ImageView Recycler Map with ImageView.<\/span><br \/>\n<em>ImageView Recycler Map Entry: \u00a0&#8211;\u00a0Key &#8211; IV1 (Object of ImageView), Value &#8211; ID1 (\u00a0Unique Id of row &#8211; Position of Row\u00a0<\/em><\/p>\n<p style=\"text-align: justify;\">2. The image (ID1) is checked in Bitmap Cache Map. If the image is found in Bitmap\u00a0Cache Map, it is set in ImageView and displayed.\u00a0If the image is NOT found in Bitmap Cache Map,\u00a0a place holder image (Default Image) is set in ImageView and a new request is queued to load it from device local storage OR download the image.<br \/>\n<em>Queue Entry: Unique Id (ID1), ImageView (IV1) and URL of Image<\/em><\/p>\n<p style=\"text-align: justify;\">3. Process the request from the Queue.<\/p>\n<p style=\"text-align: justify;\"><em><strong>CHECKPOINT 1\u00a0of 3 <\/strong>&#8211; It is possible that by the time request from the Queue is picked up for loading the image from local storage or downloading image, ListView has been scrolled by the user and ImageView object is recycled and allocated to other row with a different ID. So, we don&#8217;t need to download this image as it is not currently shown. Mapping of ImageView (IV1) and Unique ID (ID1) is checked in ImageView Recycler Map for that.<\/em><\/p>\n<p style=\"text-align: justify;\"><span style=\"text-align: justify; line-height: 1.714285714; font-size: 1rem;\">4. Load the image into Image Bitmap Cache if image is available on device local storage else downloading image. This is to be done in new thread. If mapping (See CHECKPOINT above) exists, image loading \/ downloading from server starts else we simply return from thread and that request to load \/ download is dropped.\u00a0<\/span><\/p>\n<p><span style=\"text-align: justify;\">5. If the image is available on device local storage Or it is available after downloading from server, it is put in Bitmap Cache \u00a0Map and send for display.<\/span><\/p>\n<p style=\"text-align: justify;\"><em><strong>CHECKPOINT 2 of 3\u00a0<\/strong>&#8211; It is possible that by the time image is to be loaded from device local storage (Either already available OR after download), ListView has been scrolled by the user and ImageView object is recycled and allocated to other row with a different ID. Mapping of ImageView and ID is checked in ImageView Recycler Map for that. If ImageView has been recycled, we don&#8217;t need to place this image in Bitmap Cache Map. But keep it on hard disk.<\/em><\/p>\n<p><span style=\"text-align: justify;\">6. To display the image on ImageView we post a Runnable on the UI Thread using the Handler. <\/span><\/p>\n<p style=\"text-align: justify;\"><em><span style=\"text-align: justify;\"><strong>CHECKPOINT 3 of 3<\/strong> &#8211; Just before image is set on ImageView we again check in ImageView Recycler Map if the Mapping of ImageView (IV1) and Id (ID1) exists. If the mapping exists we set the image on ImageView else the place \u00a0holder (default) image is set.<\/span><\/em><\/p>\n<p style=\"text-align: justify;\"><span style=\"line-height: 1.714285714; font-size: 1rem;\">I created Android library project for this and can import in Android application project. To use it you just have to instantiate an instance of <\/span>ImageLoader<em style=\"line-height: 1.714285714; font-size: 1rem;\"> <\/em><span style=\"line-height: 1.714285714; font-size: 1rem;\">class and call its method <\/span>displayImage()<span style=\"line-height: 1.714285714; font-size: 1rem;\"> from getView() method of Adapter.<\/span><\/p>\n<h3 style=\"text-align: justify;\"><span style=\"color: #000000;\">Main Components:<\/span><\/h3>\n<ol style=\"text-align: justify;\">\n<li><strong>ImageLoader &#8211;\u00a0<\/strong>This class provides Lazy Load concept. It uses Thread Pool to download images in parallel in worker threads . It also uses LruCache provided by Android to store\/load images without any extra efforts for memory management.\u00a0ImageLoader Class handles the Images to be displayed in ListView, Load images from cache or queue them to be download from web server (load from external storage).<\/li>\n<li><strong style=\"line-height: 1.714285714; font-size: 1rem;\">MemoryCache &#8211;\u00a0<\/strong><span style=\"line-height: 1.714285714; font-size: 1rem;\">It \u00a0contains a LruCache object.\u00a0LRUCache is a caching strategy where we use Least Recently Used (LRU) eviction policy when the cache is full and we want to add more new data to the cache.\u00a0<\/span>LruCache is given fixed size (Either number of items or size in kilobytes) to store Bitmaps. When we add more Bitmaps the least recently used Bitmaps will become candidates for garbage collection.\u00a0LRUCache cache was introduced in API level 12 (3.1) but is available through the Support Library back to 1.6.<\/li>\n<li><strong>FileCache<\/strong> &#8211; Used to create folder in external storage (or sdcard) and also clear images from file when \u00a0specified memory limit reached.<\/li>\n<li><strong>ImageLoaderRunnable<\/strong> &#8211; This is for processing the request to load the image from local device storage or download the image from server<\/li>\n<li><strong>BitmapDisplayerRunnable<\/strong> &#8211; This is for placing the image in the ImageView.<\/li>\n<\/ol>\n<h3><span style=\"color: #000000;\">Sequence Diagrams:<\/span><\/h3>\n<p>Following Sequence Diagram depicts the whole life-cycle:<\/p>\n<h4 style=\"text-align: left;\">1. Sequence Diagram &#8211; Accessing image from Cache and putting a request in Queue<\/h4>\n<p><a href=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-1.png\"><img fetchpriority=\"high\" decoding=\"async\" class=\"alignleft size-full wp-image-1610\" alt=\"InnovationM - Sequence Diagram Lazy Loading Images In Android\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-1.png\" width=\"747\" height=\"426\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-1.png 747w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-1-300x171.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-1-624x355.png 624w\" sizes=\"(max-width: 747px) 100vw, 747px\" \/><\/a><\/p>\n<h4 style=\"text-align: left;\">2. Sequence Diagram &#8211; Processing request from Queue<\/h4>\n<p><a href=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2.png\"><img decoding=\"async\" class=\"alignleft size-large wp-image-1611\" alt=\"InnovationM - Sequence Diagram Lazy Loading Images In Android\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2-1024x556.png\" width=\"625\" height=\"339\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2-1024x556.png 1024w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2-300x163.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2-624x339.png 624w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-2.png 1141w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/a><\/p>\n<h4 style=\"text-align: left;\">3. Sequence Diagram &#8211; Placing Image for display<\/h4>\n<h3><a href=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-3.png\"><img decoding=\"async\" class=\"alignleft size-full wp-image-1612\" alt=\"InnovationM - Sequence Diagram Lazy Loading Images In Android\" src=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-3.png\" width=\"658\" height=\"248\" srcset=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-3.png 658w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-3-300x113.png 300w, https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Sequence-Diagram-LazyLoadingImagesInAndroid-3-624x235.png 624w\" sizes=\"(max-width: 658px) 100vw, 658px\" \/><\/a> <span style=\"color: #000000;\">Code Snippets:<\/span><\/h3>\n<pre class=\"lang:java decode:true\" title=\"ImageLoader.java\">public class ImageLoader \r\n{\r\n\tMemoryCache memoryCache;\r\n\tFileCache fileCache;\r\n\tResources resources;\r\n\tprivate static final int DEFAULT_NO_OF_THREADS = 5;\r\n\tprivate final int imagePlaceHolderId;\r\n\tprivate Map&lt;ImageView, String&gt; recyclerMap = Collections.synchronizedMap(new WeakHashMap&lt;ImageView, String&gt;());\r\n\tExecutorService executorService;\r\n\tHandler handler = new Handler();\r\n\tprivate Map&lt;String, Boolean&gt; serverRequestMap  = Collections.synchronizedMap(new HashMap&lt;String, Boolean&gt;());\r\n\r\n\tpublic ImageLoader(Context context, int imagePlaceHolderId, int lruCacheSize, int lruCacheUnit, \r\n\t\t\tint maxFileCacheSize, String fileCacheFolder, int numberOfThreads)\r\n\t{\r\n\t\tthis.imagePlaceHolderId = imagePlaceHolderId;\r\n\t\tthis.resources = context.getResources();\r\n\r\n\t\tif(numberOfThreads &lt; 1)\r\n\t\t{\r\n\t\t\tnumberOfThreads = DEFAULT_NO_OF_THREADS;\r\n\t\t}\r\n\r\n\t\tmemoryCache = new MemoryCache(lruCacheSize, lruCacheUnit);\r\n\t\tfileCache = new FileCache(context, maxFileCacheSize, fileCacheFolder);\r\n\t\texecutorService = Executors.newFixedThreadPool(numberOfThreads);\r\n\t}\r\n\r\n\tpublic void displayImage(String imageName, String imageUrl, ImageView imageView)\r\n\t{\r\n\t\trecyclerMap.put(imageView, imageName);\r\n\t\tBitmap bitmap = memoryCache.getImageFromCache(imageName);\r\n\r\n\t\tif(bitmap!=null)\r\n\t\t{\r\n\t\t\timageView.setImageBitmap(bitmap);\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tqueuePhoto(imageName, imageUrl, imageView);\r\n\r\n\t\t\ttry\r\n\t\t\t{\r\n\t\t\t\timageView.setImageDrawable(resources.getDrawable(imagePlaceHolderId));\r\n\t\t\t}\r\n\t\t\tcatch(NotFoundException notFoundException)\r\n\t\t\t{\r\n\t\t\t\tthrow notFoundException;\r\n\t\t\t}\t\r\n\t\t}\r\n\t}\r\n\r\n\tprivate void queuePhoto(String imageName, String imageUrl, ImageView imageView)\r\n\t{\r\n\t\tImageInfo imageInfo = new ImageInfo(imageName, imageUrl, imageView);\r\n\t\texecutorService.submit(new ImageLoaderRunnable(imageInfo));\r\n\t}\r\n\r\n\tboolean imageViewReused(ImageInfo photoToLoad)\r\n\t{\r\n\t\tString imageName = recyclerMap.get(photoToLoad.getImageView());\r\n\t\tif(imageName==null || !imageName.equals(photoToLoad.getImageName()))\r\n\t\t{\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\treturn false;\r\n\t}\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:default decode:true\" title=\"ImageLoaderRunnable.java\">class ImageLoaderRunnable implements Runnable \r\n{\r\n\tImageInfo photoToLoad;\r\n\tImageLoaderRunnable(ImageInfo photoToLoad)\r\n\t{\r\n\t\tthis.photoToLoad = photoToLoad;\r\n\t}\r\n\r\n\tpublic void run() \r\n\t{\r\n\t\ttry\r\n\t\t{\r\n\t\t\tif(imageViewReused(photoToLoad))\r\n\t\t\t{ \r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tString imageName = photoToLoad.getImageName();\r\n\t\t\tString imageUrl = photoToLoad.getImageUrl();\r\n\t\t\tBitmap bitmap = null;\r\n\t\t\tBoolean isServerRequestExists = serverRequestMap.get(imageName);\r\n\t\t\tisServerRequestExists = (isServerRequestExists == null ? false : isServerRequestExists);\r\n\r\n\t\t\tif(!isServerRequestExists) \/\/If Server request not exists, take hit\r\n\t\t\t{\r\n\t\t\t\tserverRequestMap.put(imageName, true);\r\n\r\n\t\t\t\ttry\r\n\t\t\t\t{\r\n\t\t\t\t\tbitmap = getImage(imageName, imageUrl);\r\n\t\t\t\t}\r\n\t\t\t\tcatch(Exception exception)\r\n\t\t\t\t{\r\n\t\t\t\t\tserverRequestMap.put(imageName, false);\r\n\t\t\t\t\tif(imageViewReused(photoToLoad))\r\n\t\t\t\t\t{ \r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tbitmap = getImage(imageName, imageUrl);\r\n\t\t\t\t\tserverRequestMap.put(imageName, true);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(bitmap != null)\r\n\t\t\t{\r\n\t\t\t\tserverRequestMap.remove(photoToLoad.getImageName());\r\n\t\t\t\tmemoryCache.saveImageToCache(imageName, bitmap);\r\n\t\t\t}\r\n\r\n\t\t\tif(imageViewReused(photoToLoad))\r\n\t\t\t{ \r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tBitmapDisplayerRunnable bitmapDisplayer = new BitmapDisplayerRunnable(bitmap, photoToLoad);\r\n\r\n\t\t\thandler.post(bitmapDisplayer);\r\n\t\t}\r\n\t\tcatch(Throwable throwable)\r\n\t\t{\r\n\t\t\tthrowable.printStackTrace();\r\n\t\t}\r\n\t}\r\n\r\n\tpublic Bitmap getImage(String imageName, String url) throws ClientProtocolException, FileNotFoundException, InnovationMException, IOException\r\n\t{\r\n\t\tFile file = null;\r\n\t\tBitmap bitmap = null;\r\n\t\tfile = fileCache.getFileFromFileCache(imageName);\r\n\r\n\t\ttry\r\n\t\t{\r\n\t\t\tbitmap = BitmapFactory.decodeStream(new FileInputStream(file));\r\n\t\t}\r\n\t\tcatch(FileNotFoundException fileNotFoundException)\r\n\t\t{\r\n\t\t\t\/\/Consume\r\n\t\t}\r\n\r\n\t\tif(bitmap != null)\r\n\t\t{\r\n\t\t\treturn bitmap;\r\n\t\t}\r\n\t\telse\r\n\t\t{\r\n\t\t\tif(AppUtil.isImageUrlValid(url))\r\n\t\t\t{\r\n\t\t\t\t\/\/Download From WS\r\n\t\t\t\tbitmap = ImageManager.downloadBitmap(url, file);\r\n\t\t\t}\t\t\t\t\t\r\n\t\t}\r\n\r\n\t\treturn bitmap;\r\n\t}\r\n\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<pre class=\"lang:java decode:true\" title=\"BitmapDisplayerRunnable.java\">class BitmapDisplayerRunnable implements Runnable\r\n\t{\r\n\t\tBitmap bitmap;\r\n\t\tImageInfo photoToLoad;\r\n\t\tpublic BitmapDisplayerRunnable(Bitmap bitmap, ImageInfo imageInfo)\r\n\t\t{\r\n\t\t\tthis.bitmap = bitmap;\r\n\t\t\tthis.photoToLoad = imageInfo;\r\n\t\t}\r\n\r\n\t\tpublic void run()\r\n\t\t{\r\n\t\t\tif(imageViewReused(photoToLoad))\r\n\t\t\t{\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\tif(bitmap!=null)\r\n\t\t\t{\r\n\t\t\t\tphotoToLoad.getImageView().setImageBitmap(bitmap);\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\tphotoToLoad.getImageView().setImageResource(imagePlaceHolderId);\r\n\t\t\t}\r\n\t\t}\r\n\t}<\/pre>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction to Lazy Loading What is lazy loading? A little introduction of lazy loading is \u00a0it is a design pattern to defer the initialization of an object until the point at which it is needed. In simple words create objects when it is needed. Problems to Tackle Before talking about lazy loading of images, I [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1666,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,71,8],"tags":[151,159,14,152,150,165],"class_list":["post-1537","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","category-mobile","category-mobile-architecture-and-design","tag-adpater","tag-android","tag-innovationm","tag-lazy-loading","tag-listview","tag-mobile"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.4 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog\" \/>\n<meta property=\"og:description\" content=\"Introduction to Lazy Loading What is lazy loading? A little introduction of lazy loading is \u00a0it is a design pattern to defer the initialization of an object until the point at which it is needed. In simple words create objects when it is needed. Problems to Tackle Before talking about lazy loading of images, I [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/\" \/>\n<meta property=\"og:site_name\" content=\"InnovationM - Blog\" \/>\n<meta property=\"article:published_time\" content=\"2015-04-26T17:30:27+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2015-05-08T04:12:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"624\" \/>\n\t<meta property=\"og:image:height\" content=\"250\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"InnovationM Admin\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"InnovationM Admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/\"},\"author\":{\"name\":\"InnovationM Admin\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"headline\":\"Lazy Loading and Memory Management of Images in ListView in Android\",\"datePublished\":\"2015-04-26T17:30:27+00:00\",\"dateModified\":\"2015-05-08T04:12:46+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/\"},\"wordCount\":1260,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/04\\\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg\",\"keywords\":[\"Adpater\",\"Android\",\"InnovationM\",\"Lazy Loading\",\"ListView\",\"Mobile\"],\"articleSection\":[\"Android\",\"Mobile\",\"Mobile Architecture and Design\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/\",\"name\":\"Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/04\\\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg\",\"datePublished\":\"2015-04-26T17:30:27+00:00\",\"dateModified\":\"2015-05-08T04:12:46+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/04\\\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg\",\"contentUrl\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/wp-content\\\/uploads\\\/2015\\\/04\\\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg\",\"width\":624,\"height\":250,\"caption\":\"InnovationM Lazy Loading Memory Management UITableView Android\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/lazy-loading-and-memory-management-of-images-in-listview-in-android\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Lazy Loading and Memory Management of Images in ListView in Android\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/\",\"name\":\"InnovationM - Blog\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/#\\\/schema\\\/person\\\/a831bf4602d69d1fa452e3de0c8862ed\",\"name\":\"InnovationM Admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g\",\"caption\":\"InnovationM Admin\"},\"sameAs\":[\"http:\\\/\\\/www.innovationm.com\\\/\"],\"url\":\"https:\\\/\\\/www.innovationm.com\\\/blog\\\/author\\\/innovationmadmin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/","og_locale":"en_US","og_type":"article","og_title":"Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog","og_description":"Introduction to Lazy Loading What is lazy loading? A little introduction of lazy loading is \u00a0it is a design pattern to defer the initialization of an object until the point at which it is needed. In simple words create objects when it is needed. Problems to Tackle Before talking about lazy loading of images, I [&hellip;]","og_url":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/","og_site_name":"InnovationM - Blog","article_published_time":"2015-04-26T17:30:27+00:00","article_modified_time":"2015-05-08T04:12:46+00:00","og_image":[{"width":624,"height":250,"url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg","type":"image\/jpeg"}],"author":"InnovationM Admin","twitter_misc":{"Written by":"InnovationM Admin","Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#article","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/"},"author":{"name":"InnovationM Admin","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"headline":"Lazy Loading and Memory Management of Images in ListView in Android","datePublished":"2015-04-26T17:30:27+00:00","dateModified":"2015-05-08T04:12:46+00:00","mainEntityOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/"},"wordCount":1260,"commentCount":0,"image":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg","keywords":["Adpater","Android","InnovationM","Lazy Loading","ListView","Mobile"],"articleSection":["Android","Mobile","Mobile Architecture and Design"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/","url":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/","name":"Lazy Loading and Memory Management of Images in ListView in Android - InnovationM - Blog","isPartOf":{"@id":"https:\/\/www.innovationm.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#primaryimage"},"image":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#primaryimage"},"thumbnailUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg","datePublished":"2015-04-26T17:30:27+00:00","dateModified":"2015-05-08T04:12:46+00:00","author":{"@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed"},"breadcrumb":{"@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#primaryimage","url":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg","contentUrl":"https:\/\/www.innovationm.com\/blog\/wp-content\/uploads\/2015\/04\/InnovationM-Lazy-Loading-Memory-Management-ListView-Android.jpg","width":624,"height":250,"caption":"InnovationM Lazy Loading Memory Management UITableView Android"},{"@type":"BreadcrumbList","@id":"https:\/\/www.innovationm.com\/blog\/lazy-loading-and-memory-management-of-images-in-listview-in-android\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.innovationm.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Lazy Loading and Memory Management of Images in ListView in Android"}]},{"@type":"WebSite","@id":"https:\/\/www.innovationm.com\/blog\/#website","url":"https:\/\/www.innovationm.com\/blog\/","name":"InnovationM - Blog","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.innovationm.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.innovationm.com\/blog\/#\/schema\/person\/a831bf4602d69d1fa452e3de0c8862ed","name":"InnovationM Admin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/5c99d9eece9dfbc82297cf34ddd58e9fe05bb52fe66c8f6bf6c0a45bfb6d7629?s=96&r=g","caption":"InnovationM Admin"},"sameAs":["http:\/\/www.innovationm.com\/"],"url":"https:\/\/www.innovationm.com\/blog\/author\/innovationmadmin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/1537","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/comments?post=1537"}],"version-history":[{"count":0,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/posts\/1537\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media\/1666"}],"wp:attachment":[{"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/media?parent=1537"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/categories?post=1537"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.innovationm.com\/blog\/wp-json\/wp\/v2\/tags?post=1537"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}