{"id":304,"date":"2016-03-20T13:02:48","date_gmt":"2016-03-20T18:02:48","guid":{"rendered":"http:\/\/jebware.com\/blog\/?p=304"},"modified":"2020-06-05T11:13:47","modified_gmt":"2020-06-05T16:13:47","slug":"android-dev-tip-prefer-xml-drawables-instead-of-png-assets","status":"publish","type":"post","link":"https:\/\/jebware.com\/blog\/?p=304","title":{"rendered":"Android dev tip: Replace PNG assets with XML drawables"},"content":{"rendered":"<p><b>tl;dr: You\u2019ll save a <\/b><b><i>lot<\/i><\/b><b> of memory.<\/b><\/p>\n<p>The best way to fix OutOfMemoryException problems in Android is never to have them, so it\u2019s important to be proactive about limiting the amount of memory that your app uses. &nbsp;Sometimes this means bossing around your designers. &nbsp;Let me explain why with a story&#8230;<\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/button.png\" rel=\"attachment wp-att-305\"><img loading=\"lazy\" class=\"aligncenter size-medium wp-image-305\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/button-300x100.png\" alt=\"button\" width=\"300\" height=\"100\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/button-300x100.png 300w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/button.png 450w\" sizes=\"(max-width: 300px) 85vw, 300px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Your designer hands you a design with a PNG that looks like this (well, hopefully your designer hands you things that look nicer than this, since I have no idea what I\u2019m doing, but let\u2019s ignore that for a minute, shall we? &nbsp;K thx.)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It\u2019s just a little thing, just 300&#215;100 dp. &nbsp;So you lay out the screen, run the app and everything is hunky-dory, until you look at the Memory Monitor in Android Studio and notice your app\u2019s memory usage just jumped by about 1 MB.<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/png-mem-jump.png\" rel=\"attachment wp-att-306\"><img loading=\"lazy\" class=\"aligncenter wp-image-306 size-full\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/png-mem-jump.png\" alt=\"png-mem-jump\" width=\"634\" height=\"215\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/png-mem-jump.png 634w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/png-mem-jump-300x102.png 300w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<h3><span style=\"font-weight: 400;\">What the hell just happened?<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">That\u2019s no good. &nbsp;Surely adding a simple button can\u2019t cost a megabyte of memory.<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/finder-small.png\" rel=\"attachment wp-att-307\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-307\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/finder-small.png\" alt=\"finder-small\" width=\"208\" height=\"338\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/finder-small.png 208w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/finder-small-185x300.png 185w\" sizes=\"(max-width: 208px) 85vw, 208px\" \/><\/a><span style=\"font-weight: 400;\">You look at the PNG you just added, but it\u2019s only 10<\/span> <span style=\"font-weight: 400;\">KB. &nbsp;That can\u2019t be the problem, can it? &nbsp;Turns out, it is. &nbsp;What you\u2019re looking at in Finder is the compressed image file, but Android doesn\u2019t keep the file compressed when it loads. &nbsp;It renders your PNG to a <\/span><a href=\"http:\/\/developer.android.com\/reference\/android\/graphics\/Bitmap.html\"><span style=\"font-weight: 400;\">Bitmap<\/span><\/a><span style=\"font-weight: 400;\">, which is the most un-compressed way to store an image. &nbsp;It\u2019s just a big matrix of pixels with a color value for each pixel. &nbsp;By default, Android uses the <\/span><span style=\"font-weight: 400;\">ARGB_8888 format<\/span><span style=\"font-weight: 400;\">&nbsp;which uses 4 bytes per pixel. &nbsp;And oh yeah, we\u2019re looking at an XXHDPI device, so our 300dp width is actually 900 pixels. &nbsp;That means our \u201clittle\u201d 900&#215;300 pixel image is using 1,080,000 bytes (1.03 MB) for its Bitmap. &nbsp;<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/mem-dump-byte-array.png\" rel=\"attachment wp-att-308\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-308\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/mem-dump-byte-array.png\" alt=\"mem-dump-byte-array\" width=\"600\" height=\"249\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/mem-dump-byte-array.png 600w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/mem-dump-byte-array-300x125.png 300w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><\/p>\n<p><span style=\"font-weight: 400;\">Yeah, that really sucks.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">So are you stuck with the sad fact that you\u2019re now 1 MB closer to exploding your app by running out of memory? &nbsp;Do you DM your designer on Slack and tell them they\u2019re a bad person and they\u2019re killing the app? &nbsp;(Pro-tip: don\u2019t ever do that)<\/span><\/p>\n<p><span style=\"font-weight: 400;\">There\u2019s a better way. &nbsp;You can draw the same thing to the screen using an XML Drawable and a Button.<\/span><\/p>\n<p><script src=\"https:\/\/gist.github.com\/jebware\/75fc17e3d7eb2d63e2cb.js\"><\/script><\/p>\n<p><script src=\"https:\/\/gist.github.com\/jebware\/3e6b9fb54f10ecfbd803.js\"><\/script><\/p>\n<p><span style=\"font-weight: 400;\">Now let\u2019s check that memory usage again.<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/xml-tiny-jump.png\" rel=\"attachment wp-att-309\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-309\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/xml-tiny-jump.png\" alt=\"xml-tiny-jump\" width=\"703\" height=\"208\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/xml-tiny-jump.png 703w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/xml-tiny-jump-300x89.png 300w\" sizes=\"(max-width: 709px) 85vw, (max-width: 909px) 67vw, (max-width: 984px) 61vw, (max-width: 1362px) 45vw, 600px\" \/><\/a><span style=\"font-weight: 400;\">Our XML-based drawable is using 504 bytes in memory. &nbsp;Oh that\u2019s nice.<\/span><\/p>\n<h3><span style=\"font-weight: 400;\">Moral of the Story<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">Now obviously this won\u2019t work for <\/span><i><span style=\"font-weight: 400;\">every<\/span><\/i><span style=\"font-weight: 400;\"> asset; once you get past basic shapes, you\u2019ll still need assets for anything complex. &nbsp;But by being vigilant, and replacing simple assets with XML drawables, you delay the time when you\u2019ll face the inevitable OutOfMemoryException.<\/span><\/p>\n<p><a href=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/4865622-1.jpg\" rel=\"attachment wp-att-313\"><img loading=\"lazy\" class=\"aligncenter size-full wp-image-313\" src=\"http:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/4865622-1.jpg\" alt=\"4865622\" width=\"400\" height=\"382\" srcset=\"https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/4865622-1.jpg 400w, https:\/\/jebware.com\/blog\/wp-content\/uploads\/2016\/03\/4865622-1-300x287.jpg 300w\" sizes=\"(max-width: 400px) 85vw, 400px\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>tl;dr: You\u2019ll save a lot of memory. The best way to fix OutOfMemoryException problems in Android is never to have them, so it\u2019s important to be proactive about limiting the amount of memory that your app uses. &nbsp;Sometimes this means bossing around your designers. &nbsp;Let me explain why with a story&#8230; Your designer hands you &hellip; <a href=\"https:\/\/jebware.com\/blog\/?p=304\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Android dev tip: Replace PNG assets with XML drawables&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_mi_skip_tracking":false,"twitterCardType":"","cardImageID":0,"cardImage":"","cardTitle":"","cardDesc":"","cardImageAlt":"","cardPlayer":"","cardPlayerWidth":0,"cardPlayerHeight":0,"cardPlayerStream":"","cardPlayerCodec":""},"categories":[4],"tags":[],"_links":{"self":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/304"}],"collection":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=304"}],"version-history":[{"count":6,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/304\/revisions"}],"predecessor-version":[{"id":631,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/304\/revisions\/631"}],"wp:attachment":[{"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/jebware.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}